包含以下内容:
1 数据读写
1.1 数据读取
读取.csv或者读取.tsv文件:
import pandas as pd
result_df = pd.read_csv("filename.csv") # csv
result_df = pd.read_csv("filename.tsv", sep='\t'). # tsv
在使用read_csv时,有一些参数,挺实用的:
- 设置索引: index_col=0 设置第一列为索引,这样就不会读了之后,又加一个索引
- 只读取某些列: usecols = ['colname1', 'colname2'] :只读取其中的某些列
- 设置数据类型:dtype = {'colname1': int, 'colname2': str} :按类型读取这些列,注意,如果类型不匹配,会报错
- 错误处理:error_bad_lines = False :对不符合csv规范的行,跳过
如果想知道哪些字段为空,记得:
test_df = test_df.fillna("")
之后取数据判断是否为空:
if test_df.iloc[i]["col_name"].strip() == "":
1.1 写数据
写入csv中文乱码,解决方案:
result_df.to_csv("xxx.csv", encoding="utf_8_sig")
写入csv时,不写入索引:
result_df.to_csv("xxx.csv", index=None)
2 数据预处理
2.1 处理数据类型错误
数据类型错误比如你的某一列"age"表示的是年龄,但是其中有些数据错误,含有字母而无法转变为整型。即下面这行代码报错:
result_df = pd.read_csv("filename.csv", dtype={'age': int},)
这时,需要不带类型的读取这一列数据,然后使用pd.to_numeric处理:
result_df = pd.read_csv("filename.csv", )
result_df.age = pd.to_numeric(result_df.age, errors='coerce', )
# 其中,errors='coerce' results in NaN for entries that can't be converted
result_df = result_df[result_df.age.notnull()]. # 只取不为空的部分
# 因为这里是浮点型,你可以舍弃精度,转为整型:
result_df['age'] = result_df['age'].astype(int)
# 可以取多行同时不为空的部分:
# result_df = result_df[result_df.age.notnull() & result.height.notnull()]
2.2 排序-按照某些列排序:
res = df.sort_values(by=['A', 'B'], ascending=[True, True])
注意排序后,index并没有变,也就是说,你按index取数据,res.loc[i, :],一个递增的i取出的数据并不是递增的。
所以一般建议,排序后,重排index:
res = res.reset_index()
2.3 列名
2.3.1 列名的获取与修改
打印列名 、 获取每一列的数据类型
print(df.columns)
print(df.dtypes)
修改列名:
df.rename(columns={'old_name1':'new_name1', 'old_name2':'new_name2'},inplace=True)
# 不用赋值,用了 inplace=True,意味着df的列名就在原来的变量上改了
# 也可以直接给列名整体赋值
df.columns=['new_name1','new_name2','new_name3']
2.3.2 根据列名取数据,增加列
根据列名取某几列的数据:
如取出'col1', 'col2', 'col3'这三列的数据,形成一个新的DataFrame
df = df.loc[:, ['col1', 'col2', 'col3',]]
这里注意loc和iloc的区别,闲话少叙,直接上结论:
建议:取数据用iloc,改数据用loc:
df.loc[i, 'col_name'] = 6 # 用这种方式给行索引为i,'col_name'列的数据赋值
df.loc[i, 'col_name'] = df.iloc[j]['col_name2'] # 取出另一个数据,用来赋值
这里需要注意的是loc中的i是索引,并不是第i行的意思。一般情况下二者是一致的,但是当你取部分数据的时候就会有问题,比如你
df = df[100:200]
这样取出第100-200个数据,你的数据长度是100,但是索引是100-200.
根据已有的列构成新的列:
如你现在有一列表示日期,你想把年份单独取出来构成新的一列,然后统计不同年份的数据有多少:
# ’DATE’列的格式:06/18/2007 我们切片取[6:10]就是年份了
crime_df['year'] = crime_df['DATE'].str[6:10]
再比如,你希望有一个新的列,是另外几个列的拼接:
注意这样拼接,得转化成str所以这里都用map处理了。
merged_df['group'] = merged_df['section'].map(str) + merged_df['ipc_class'].map(str) + merged_df['subclass'].map(str)
2.4 日期与时间-datetime的使用:
将一列(String)转化成datetime格式:
# 假设原本的'dt'列是形如 “2020-12-01 04:34:22” 的字符串
df['dt'] = pd.to_datetime(df['dt'], format='%Y-%m-%d %H:%M:%S')
提取某段时间的数据:
https://blog.csdn.net/caoxinjian423/article/details/113029894
https://blog.csdn.net/qq_38412868/article/details/107445068
上面这两篇文章讲的非常详细,下面我摘录几个常用的:
# 如下面这行,提取小时在16-23之间的数据
df= df[df['dt'].dt.hour.isin(np.arange(16, 24))]
# 获取一月份到四月份的数据:
df[df['dt'].dt.month.isin(np.arange(1, 5))]
# df['日期'].dt.weekday # 返回一周中的星期几,0代表星期一,6代表星期天
2.5 拼接
最常用的:按某一列拼接,你的两个df要有一个共同的列名:
result = pd.merge(left, right, on='colname')
3 数据修改、初始化
3.1 对某个元素的赋值与取值
赋值有多种方法,这里我推荐用loc给指定的单元赋值(使用同样的方法,可以取出指定位置的值),不会报那个你没copy的warning:
df.loc[index, 'COLNAME'] = VALUE
# index 索引,非常适用于外面套一个for循环的情况
# 'COLNAME':列名
# VALUE:值
3.2 往空的DataFrame里加东西
先构建一个空的DataFrame,然后一行一行往里面加东西:
columns = ["col1", "col2", "col3"]. # 先把列明确定好
result_df = pd.DataFrame(columns=columns)
# 这种方式,你可以指定你插入的数据是哪些列的 ,如果是完整的一行,那就直接跟列名列表相等就好
df = df.append(pd.DataFrame([new_line], columns=columns))
2.3 构造新的列
新增一列,并赋初值
test_df["new_col_name"] = 0
4 数据分析
4.1 单列统计
4.1.1 统计不同元素个数
统计某一列不同种类的元素的个数。如:统计sex这一列(所得结果为男女各有多少人)
它的输出结果是数目多的在前面,所以你也可以用它来查看着一列是否有重复项。
result = pd.value_counts(df['sex'])
print(result)
这个统计结果是Series类型的如果要转为DataFrame,要这样做:
dict_result = {'col1':result.index,'col2':result.values}
df = pd.DataFrame(dict_result)
4.2 数据采样
如:采样200个数据
test_df.sample(200)