注:学习笔记基于文彤老师的pandas的系列课程
课程链接:https://study.163.com/course/courseMain.htm?courseId=1005124008&share=1&shareId=1146477588
# 设定系统环境
import pandas as pd
pd.options.display.max_rows = 10 # 设定自由列表输出最多为10行
pd.__version__ # 显示当前Pandas版本号,默认输出最后一行内容(即使没有打印输出)
'1.1.0'
1.数据清洗
1.1 处理缺失值
系统默认的缺失值设定
系统默认的缺失值
None和np.nan #尽量要使用np.nan
确定相应数值是否为缺失值
df.isna() # 别名为isnull,反函数为notna
df2 = pd.read_csv("univ.csv", encoding ="GBK")#使用英文名称,否则可能会报错
#把文件放到了该目录下,因此不需要再写路径,注意编码要写
df2
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北京大学 | 100.00 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 |
1 | 2 | 清华大学 | 98.50 | 理工 | 北京 | 北京市 | 中国研究型 | 教育部 |
2 | 3 | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | 4 | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | 5 | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98 | 首都医科大学 | 63.32 | 医药 | 北京 | 北京市 | 区域特色研究型 | 北京市 |
98 | 99 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | 100 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
import numpy as np
df2.名次.iloc[:3]=None
df2
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | NaN | 北京大学 | 100.00 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 |
1 | NaN | 清华大学 | 98.50 | 理工 | 北京 | 北京市 | 中国研究型 | 教育部 |
2 | NaN | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | 4.0 | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | 5.0 | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96.0 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97.0 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98.0 | 首都医科大学 | 63.32 | 医药 | 北京 | 北京市 | 区域特色研究型 | 北京市 |
98 | 99.0 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | 100.0 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
df2.名次.isna()
0 True
1 True
2 True
3 False
4 False
...
95 False
96 False
97 False
98 False
99 False
Name: 名次, Length: 100, dtype: bool
df2.名次.iloc[:5] = np.nan
df2.名次.isna()
0 True
1 True
2 True
3 True
4 True
...
95 False
96 False
97 False
98 False
99 False
Name: 名次, Length: 100, dtype: bool
None和np.nan的核心区别:能否进行比较
None == None
True
np.nan == np.nan
False
设定inf和-inf是否被认定为缺失值(正无穷大和负无穷大)
pd.options.mode.use_inf_as_na#默认不认定
False
处理自定义缺失值
目前Pandas不支持设定自定义缺失值,因此只能考虑将其替换为系统缺失值
df.replace(‘自定义缺失值’, np.nan)
df2.所在省份.replace("北京", np.nan)
0 NaN
1 NaN
2 上海
3 湖北
4 浙江
...
95 浙江
96 安徽
97 NaN
98 江苏
99 山西
Name: 所在省份, Length: 100, dtype: object
# 设定为None后的效果完全不同
df2.所在省份.replace("北京", None)#None若无新的替换值,可能保留原来,或采用上面的
#因此None尽量少用
0 北京
1 北京
2 上海
3 湖北
4 浙江
..
95 浙江
96 安徽
97 安徽
98 江苏
99 山西
Name: 所在省份, Length: 100, dtype: object
df2na = df2.replace(["北京", 100], [np.nan, np.nan])# 后面的中括号可以简写
#简写为一个np.nan
df2na
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | NaN | 北京大学 | NaN | 综合 | NaN | 北京市 | 中国研究型 | 教育部 |
1 | NaN | 清华大学 | 98.50 | 理工 | NaN | 北京市 | 中国研究型 | 教育部 |
2 | NaN | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | NaN | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | NaN | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96.0 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97.0 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98.0 | 首都医科大学 | 63.32 | 医药 | NaN | 北京市 | 区域特色研究型 | 北京市 |
98 | 99.0 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | NaN | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
标识缺失值案例
标识缺失值
df.isna()
检查相应的数据是否为缺失值
df.isnull()
df2na.replace(["北京", 100],[np.nan, np.nan]).isna()
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | True | False | True | False | True | False | False | False |
1 | True | False | False | False | True | False | False | False |
2 | True | False | False | False | False | False | False | False |
3 | True | False | False | False | False | False | False | False |
4 | True | False | False | False | False | False | False | False |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | False | False | False | False | False | False | False | False |
96 | False | False | False | False | False | False | False | False |
97 | False | False | False | False | True | False | False | False |
98 | False | False | False | False | False | False | False | False |
99 | True | False | False | False | False | False | False | False |
100 rows × 8 columns
检查多个单元格的取值是否为指定数值
df.any(
axis : {index (0), columns (1)}
skipna = True : 检查时是否忽略缺失值
level = None : 多重索引时指定具体的级别
)
df.all(
axis : {index (0), columns (1)}
skipna = True : 检查时是否忽略缺失值
level = None : 多重索引时指定具体的级别
)
df2na.isna().any(1)
0 True
1 True
2 True
3 True
4 True
...
95 False
96 False
97 True
98 False
99 True
Length: 100, dtype: bool
df2na[df2na.isna().any(1)]
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | NaN | 北京大学 | NaN | 综合 | NaN | 北京市 | 中国研究型 | 教育部 |
1 | NaN | 清华大学 | 98.50 | 理工 | NaN | 北京市 | 中国研究型 | 教育部 |
2 | NaN | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | NaN | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | NaN | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
89 | 90.0 | 对外经济贸易大学 | 63.77 | 财经 | NaN | 北京市 | 区域特色研究型 | 教育部 |
91 | 92.0 | 首都师范大学 | 63.73 | 师范 | NaN | 北京市 | 区域特色研究型 | 北京市 |
92 | 93.0 | 华北电力大学 | 63.66 | 理工 | NaN | 北京市 | 区域特色研究型 | 教育部 |
97 | 98.0 | 首都医科大学 | 63.32 | 医药 | NaN | 北京市 | 区域特色研究型 | 北京市 |
99 | NaN | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
26 rows × 8 columns
填充缺失值
df.fillna(
value : 用于填充缺失值的数值(也可以提供dict/Series/DataFrame以进一步指明哪些索引/列会被替换,不能使用 list)
method = None : 有索引时具体的填充方法,向前填充,向后填充等
limit = None : 指定了method后设定具体的最大填充步长,大于此步长不能填充
axis : {0 or ‘index’, 1 or ‘columns’}
inplace = False
)
在构建新索引的同时完成缺失值的填充任务
df.reindex(labels = None, fill_value = np.NaN)
df2.replace(["北京", 100],[np.nan, np.nan]).fillna('未知')
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | 未知 | 北京大学 | 未知 | 综合 | 未知 | 北京市 | 中国研究型 | 教育部 |
1 | 未知 | 清华大学 | 98.5 | 理工 | 未知 | 北京市 | 中国研究型 | 教育部 |
2 | 未知 | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | 未知 | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | 未知 | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98 | 首都医科大学 | 63.32 | 医药 | 未知 | 北京市 | 区域特色研究型 | 北京市 |
98 | 99 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | 未知 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
df2.replace(["北京", 100, 1, 2, 3], np.nan).fillna(df2.mean())
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | 52.905263 | 北京大学 | 68.5061 | 综合 | NaN | 北京市 | 中国研究型 | 教育部 |
1 | 52.905263 | 清华大学 | 98.5000 | 理工 | NaN | 北京市 | 中国研究型 | 教育部 |
2 | 52.905263 | 复旦大学 | 82.7900 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | 52.905263 | 武汉大学 | 82.4300 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | 52.905263 | 浙江大学 | 82.3800 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96.000000 | 浙江师范大学 | 63.3700 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97.000000 | 安徽大学 | 63.3400 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98.000000 | 首都医科大学 | 63.3200 | 医药 | NaN | 北京市 | 区域特色研究型 | 北京市 |
98 | 99.000000 | 江南大学 | 63.3100 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | 52.905263 | 山西大学 | 63.2900 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
df2.mean()
名次 52.905263
总分 68.506100
dtype: float64
删除缺失值
df.dropna(
axis = 0 : {0 or ‘index’, 1 or ‘columns’}
how = any : {‘any’, ‘all’}
any : 任何一个为NA就删除
all : 所有的都是NA才删除
thresh = None : 删除的数量阈值,int
subset : 希望在处理中包括的行/列子集
inplace = False :
)
df = pd.DataFrame([[np.nan, 2, np.nan, 0], [3, 4, np.nan, 1],
[np.nan, np.nan, np.nan, 5]],
columns=list('ABCD'))
df
A | B | C | D | |
---|---|---|---|---|
0 | NaN | 2.0 | NaN | 0 |
1 | 3.0 | 4.0 | NaN | 1 |
2 | NaN | NaN | NaN | 5 |
df.dropna(axis=1, how='all')
A | B | D | |
---|---|---|---|
0 | NaN | 2.0 | 0 |
1 | 3.0 | 4.0 | 1 |
2 | NaN | NaN | 5 |
1.2数据查重
标识出重复的行,所谓的重复第一个是保留,从第二个算起是重复
标识出重复行的意义在于进一步检查重复原因,以便将可能的错误数据加以修改
duplicated
df2['dup'] = df2.duplicated(['类型', '所在省份'])
df2
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | dup | |
---|---|---|---|---|---|---|---|---|---|
0 | NaN | 北京大学 | 100.00 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 | False |
1 | NaN | 清华大学 | 98.50 | 理工 | 北京 | 北京市 | 中国研究型 | 教育部 | False |
2 | NaN | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 | False |
3 | NaN | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 | False |
4 | NaN | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96.0 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 | False |
96 | 97.0 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 | False |
97 | 98.0 | 首都医科大学 | 63.32 | 医药 | 北京 | 北京市 | 区域特色研究型 | 北京市 | True |
98 | 99.0 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 | True |
99 | 100.0 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 | False |
100 rows × 9 columns
利用索引进行重复行标识
df.index.duplicated()
df2[df2.set_index(['类型', '所在省份']).index.duplicated()]
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | dup | |
---|---|---|---|---|---|---|---|---|---|
5 | 6.0 | 中国人民大学 | 81.98 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 | True |
6 | 7.0 | 上海交通大学 | 81.76 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 | True |
23 | 24.0 | 东南大学 | 71.35 | 综合 | 江苏 | 南京市 | 中国研究型 | 教育部 | True |
24 | 25.0 | 北京航空航天大学 | 70.58 | 理工 | 北京 | 北京市 | 中国研究型 | 工业和信息化部 | True |
28 | 29.0 | 大连理工大学 | 68.84 | 理工 | 辽宁 | 大连市 | 中国研究型 | 教育部 | True |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
89 | 90.0 | 对外经济贸易大学 | 63.77 | 财经 | 北京 | 北京市 | 区域特色研究型 | 教育部 | True |
91 | 92.0 | 首都师范大学 | 63.73 | 师范 | 北京 | 北京市 | 区域特色研究型 | 北京市 | True |
92 | 93.0 | 华北电力大学 | 63.66 | 理工 | 北京 | 北京市 | 区域特色研究型 | 教育部 | True |
97 | 98.0 | 首都医科大学 | 63.32 | 医药 | 北京 | 北京市 | 区域特色研究型 | 北京市 | True |
98 | 99.0 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 | True |
38 rows × 9 columns
直接删除重复的行
若里面不写参数,则默认所有的内容一样的时候算重复
df.drop_duplicates(
subset : 按照指定列进行去重,默认为使用所有列
keep = ‘first’ : 是否直接删除有重复的所有记录
first : 保留第一条重复记录
last : 保留最后一条重复记录
False : 删除全部的重复记录,包括第一次出现的
inplace = False
)
df2.drop_duplicates(['类型', '所在省份'])
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | dup | |
---|---|---|---|---|---|---|---|---|---|
0 | NaN | 北京大学 | 100.00 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 | False |
1 | NaN | 清华大学 | 98.50 | 理工 | 北京 | 北京市 | 中国研究型 | 教育部 | False |
2 | NaN | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 | False |
3 | NaN | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 | False |
4 | NaN | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
93 | 93.0 | 浙江工业大学 | 63.66 | 理工 | 浙江 | 杭州市 | 区域特色研究型 | 浙江省 | False |
94 | 95.0 | 华南农业大学 | 63.64 | 农林 | 广东 | 广州市 | 区域特色研究型 | 广东省 | False |
95 | 96.0 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 | False |
96 | 97.0 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 | False |
99 | 100.0 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 | False |
62 rows × 9 columns
df2.drop_duplicates(['类型', '所在省份'], keep = False)
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | dup | |
---|---|---|---|---|---|---|---|---|---|
3 | NaN | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 | False |
4 | NaN | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 | False |
8 | 9.0 | 国防科学技术大学 | 80.31 | 理工 | 湖南 | 长沙市 | 中国研究型 | 中央军委 | False |
10 | 11.0 | 吉林大学 | 76.01 | 综合 | 吉林 | 长春市 | 中国研究型 | 教育部 | False |
13 | 14.0 | 四川大学 | 74.99 | 综合 | 四川 | 成都市 | 中国研究型 | 教育部 | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
93 | 93.0 | 浙江工业大学 | 63.66 | 理工 | 浙江 | 杭州市 | 区域特色研究型 | 浙江省 | False |
94 | 95.0 | 华南农业大学 | 63.64 | 农林 | 广东 | 广州市 | 区域特色研究型 | 广东省 | False |
95 | 96.0 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 | False |
96 | 97.0 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 | False |
99 | 100.0 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 | False |
42 rows × 9 columns
利用查重标识结果直接删除
df[~df.duplicated()]
df2[~df2.duplicated(['类型', '所在省份'])]
类型 | 所在省份 | 名次 | 学校名称 | 总分 | 所在城市 | 办学方向 | 主管部门 | dup | |
---|---|---|---|---|---|---|---|---|---|
0 | 综合 | 北京 | NaN | 北京大学 | 100.00 | 北京市 | 中国研究型 | 教育部 | False |
1 | 理工 | 北京 | NaN | 清华大学 | 98.50 | 北京市 | 中国研究型 | 教育部 | False |
2 | 综合 | 上海 | NaN | 复旦大学 | 82.79 | 上海市 | 中国研究型 | 教育部 | False |
3 | 综合 | 湖北 | NaN | 武汉大学 | 82.43 | 武汉市 | 中国研究型 | 教育部 | False |
4 | 综合 | 浙江 | NaN | 浙江大学 | 82.38 | 杭州市 | 中国研究型 | 教育部 | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
93 | 理工 | 浙江 | 93.0 | 浙江工业大学 | 63.66 | 杭州市 | 区域特色研究型 | 浙江省 | False |
94 | 农林 | 广东 | 95.0 | 华南农业大学 | 63.64 | 广州市 | 区域特色研究型 | 广东省 | False |
95 | 师范 | 浙江 | 96.0 | 浙江师范大学 | 63.37 | 金华市 | 区域特色研究型 | 浙江省 | False |
96 | 综合 | 安徽 | 97.0 | 安徽大学 | 63.34 | 合肥市 | 区域研究型 | 安徽省 | False |
99 | 综合 | 山西 | 100.0 | 山西大学 | 63.29 | 太原市 | 区域研究型 | 山西省 | False |
62 rows × 9 columns
1.3直接比较数据框/变量列
df.compare( # pandas 1.1版新增
df : 希望进行比较的另一个df名称
align_axis = 1 : 按行还是列方向进行对比结果的汇总输出,{0 or ‘index’, 1 or ‘columns’}
keep_shape = False : 是否在结果中保留全部行列,而不是只输出有差异的行列
keep_equal = False : 是否在结果中保留无差异的行/列,不保留则均替换为nan
) # 返回:展示所对比的两个数据框差异的结果数据框
df2 = pd.read_csv("univ.csv", encoding ="GBK")#使用英文名称,否则可能会报错
#把文件放到了该目录下,因此不需要再写路径,注意编码要写
df2
名次 | 学校名称 | 总分 | 类型 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北京大学 | 100.00 | 综合 | 北京 | 北京市 | 中国研究型 | 教育部 |
1 | 2 | 清华大学 | 98.50 | 理工 | 北京 | 北京市 | 中国研究型 | 教育部 |
2 | 3 | 复旦大学 | 82.79 | 综合 | 上海 | 上海市 | 中国研究型 | 教育部 |
3 | 4 | 武汉大学 | 82.43 | 综合 | 湖北 | 武汉市 | 中国研究型 | 教育部 |
4 | 5 | 浙江大学 | 82.38 | 综合 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96 | 浙江师范大学 | 63.37 | 师范 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
96 | 97 | 安徽大学 | 63.34 | 综合 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
97 | 98 | 首都医科大学 | 63.32 | 医药 | 北京 | 北京市 | 区域特色研究型 | 北京市 |
98 | 99 | 江南大学 | 63.31 | 综合 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
99 | 100 | 山西大学 | 63.29 | 综合 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 8 columns
df2=df2.set_index(["类型","学校名称"])
df2
名次 | 总分 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | ||
---|---|---|---|---|---|---|---|
类型 | 学校名称 | ||||||
综合 | 北京大学 | 1 | 100.00 | 北京 | 北京市 | 中国研究型 | 教育部 |
理工 | 清华大学 | 2 | 98.50 | 北京 | 北京市 | 中国研究型 | 教育部 |
综合 | 复旦大学 | 3 | 82.79 | 上海 | 上海市 | 中国研究型 | 教育部 |
武汉大学 | 4 | 82.43 | 湖北 | 武汉市 | 中国研究型 | 教育部 | |
浙江大学 | 5 | 82.38 | 浙江 | 杭州市 | 中国研究型 | 教育部 | |
... | ... | ... | ... | ... | ... | ... | ... |
师范 | 浙江师范大学 | 96 | 63.37 | 浙江 | 金华市 | 区域特色研究型 | 浙江省 |
综合 | 安徽大学 | 97 | 63.34 | 安徽 | 合肥市 | 区域研究型 | 安徽省 |
医药 | 首都医科大学 | 98 | 63.32 | 北京 | 北京市 | 区域特色研究型 | 北京市 |
综合 | 江南大学 | 99 | 63.31 | 江苏 | 无锡市 | 区域特色研究型 | 教育部 |
山西大学 | 100 | 63.29 | 山西 | 太原市 | 区域研究型 | 山西省 |
100 rows × 6 columns
dftmp = df2.copy()
dftmp.loc[('综合', '北京大学'), '办学方向'] = np.nan
dftmp.head()
名次 | 总分 | 所在省份 | 所在城市 | 办学方向 | 主管部门 | ||
---|---|---|---|---|---|---|---|
类型 | 学校名称 | ||||||
综合 | 北京大学 | 1 | 100.00 | 北京 | 北京市 | NaN | 教育部 |
理工 | 清华大学 | 2 | 98.50 | 北京 | 北京市 | 中国研究型 | 教育部 |
综合 | 复旦大学 | 3 | 82.79 | 上海 | 上海市 | 中国研究型 | 教育部 |
武汉大学 | 4 | 82.43 | 湖北 | 武汉市 | 中国研究型 | 教育部 | |
浙江大学 | 5 | 82.38 | 浙江 | 杭州市 | 中国研究型 | 教育部 |
df2.compare(dftmp)
办学方向 | |||
---|---|---|---|
self | other | ||
类型 | 学校名称 | ||
综合 | 北京大学 | 中国研究型 | NaN |
df2.compare(dftmp, align_axis = 0)#按行输出
办学方向 | |||
---|---|---|---|
类型 | 学校名称 | ||
综合 | 北京大学 | self | 中国研究型 |
other | NaN |
df2.compare(dftmp)[('办学方向', 'self')]#列,行
类型 学校名称
综合 北京大学 中国研究型
Name: (办学方向, self), dtype: object
Series.compare( #列和df大多数情况下可以通用
other
align_axis = 1
keep_shape = False
keep_equal = False
)
df2.办学方向.compare(dftmp.办学方向)
self | other | ||
---|---|---|---|
类型 | 学校名称 | ||
综合 | 北京大学 | 中国研究型 | NaN |
df2.办学方向.compare(dftmp.办学方向, align_axis = 0)
类型 学校名称
综合 北京大学 self 中国研究型
other NaN
Name: 办学方向, dtype: object
实战:进一步整理PM2.5数据
要求:
PM2.5数据中数值-999表示缺失,请将这些数据替换为np.nan
基于上述处理结果,删除缺失值记录
在数据中查找到PM2.5数值完全相同的记录
在数据中查找到同一年中PM2.5数值完全相同的记录
bj
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
0 | Beijing | 2008-04-08 15:00 | 2008 | 4 | 8 | 15 | 207 | 1 Hr | Valid |
1 | Beijing | 2008-04-08 16:00 | 2008 | 4 | 8 | 16 | 180 | 1 Hr | Valid |
2 | Beijing | 2008-04-08 17:00 | 2008 | 4 | 8 | 17 | 152 | 1 Hr | Valid |
3 | Beijing | 2008-04-08 18:00 | 2008 | 4 | 8 | 18 | 162 | 1 Hr | Valid |
4 | Beijing | 2008-04-08 19:00 | 2008 | 4 | 8 | 19 | 171 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4339 | Beijing | 6/30/2017 19:00 | 2017 | 6 | 30 | 19 | 51 | 1 Hr | Valid |
4340 | Beijing | 6/30/2017 20:00 | 2017 | 6 | 30 | 20 | 68 | 1 Hr | Valid |
4341 | Beijing | 6/30/2017 21:00 | 2017 | 6 | 30 | 21 | 61 | 1 Hr | Valid |
4342 | Beijing | 6/30/2017 22:00 | 2017 | 6 | 30 | 22 | 49 | 1 Hr | Valid |
4343 | Beijing | 6/30/2017 23:00 | 2017 | 6 | 30 | 23 | 55 | 1 Hr | Valid |
79559 rows × 9 columns
bj=bj.replace(-999, np.nan)#-999不要加引号
bj[bj.isna().any(1)]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
694 | Beijing | 2008-05-07 13:00 | 2008 | 5 | 7 | 13 | NaN | 1 Hr | Missing |
695 | Beijing | 2008-05-07 14:00 | 2008 | 5 | 7 | 14 | NaN | 1 Hr | Missing |
863 | Beijing | 2008-05-14 14:00 | 2008 | 5 | 14 | 14 | NaN | 1 Hr | Missing |
864 | Beijing | 2008-05-14 15:00 | 2008 | 5 | 14 | 15 | NaN | 1 Hr | Missing |
1027 | Beijing | 2008-05-21 10:00 | 2008 | 5 | 21 | 10 | NaN | 1 Hr | Missing |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4079 | Beijing | 6/19/2017 23:00 | 2017 | 6 | 19 | 23 | NaN | 1 Hr | Missing |
4080 | Beijing | 6/20/2017 0:00 | 2017 | 6 | 20 | 0 | NaN | 1 Hr | Missing |
4081 | Beijing | 6/20/2017 1:00 | 2017 | 6 | 20 | 1 | NaN | 1 Hr | Missing |
4184 | Beijing | 6/24/2017 8:00 | 2017 | 6 | 24 | 8 | NaN | 1 Hr | Missing |
4218 | Beijing | 6/25/2017 18:00 | 2017 | 6 | 25 | 18 | NaN | 1 Hr | Missing |
4459 rows × 9 columns
bj=bj.dropna(axis=0, how='any')
bj
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
0 | Beijing | 2008-04-08 15:00 | 2008 | 4 | 8 | 15 | 207.0 | 1 Hr | Valid |
1 | Beijing | 2008-04-08 16:00 | 2008 | 4 | 8 | 16 | 180.0 | 1 Hr | Valid |
2 | Beijing | 2008-04-08 17:00 | 2008 | 4 | 8 | 17 | 152.0 | 1 Hr | Valid |
3 | Beijing | 2008-04-08 18:00 | 2008 | 4 | 8 | 18 | 162.0 | 1 Hr | Valid |
4 | Beijing | 2008-04-08 19:00 | 2008 | 4 | 8 | 19 | 171.0 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4339 | Beijing | 6/30/2017 19:00 | 2017 | 6 | 30 | 19 | 51.0 | 1 Hr | Valid |
4340 | Beijing | 6/30/2017 20:00 | 2017 | 6 | 30 | 20 | 68.0 | 1 Hr | Valid |
4341 | Beijing | 6/30/2017 21:00 | 2017 | 6 | 30 | 21 | 61.0 | 1 Hr | Valid |
4342 | Beijing | 6/30/2017 22:00 | 2017 | 6 | 30 | 22 | 49.0 | 1 Hr | Valid |
4343 | Beijing | 6/30/2017 23:00 | 2017 | 6 | 30 | 23 | 55.0 | 1 Hr | Valid |
75100 rows × 9 columns
bj[bj.duplicated('Value')]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
10 | Beijing | 2008-04-09 01:00 | 2008 | 4 | 9 | 1 | 64.0 | 1 Hr | Valid |
15 | Beijing | 2008-04-09 06:00 | 2008 | 4 | 9 | 6 | 69.0 | 1 Hr | Valid |
16 | Beijing | 2008-04-09 07:00 | 2008 | 4 | 9 | 7 | 69.0 | 1 Hr | Valid |
17 | Beijing | 2008-04-09 08:00 | 2008 | 4 | 9 | 8 | 64.0 | 1 Hr | Valid |
18 | Beijing | 2008-04-09 09:00 | 2008 | 4 | 9 | 9 | 69.0 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4339 | Beijing | 6/30/2017 19:00 | 2017 | 6 | 30 | 19 | 51.0 | 1 Hr | Valid |
4340 | Beijing | 6/30/2017 20:00 | 2017 | 6 | 30 | 20 | 68.0 | 1 Hr | Valid |
4341 | Beijing | 6/30/2017 21:00 | 2017 | 6 | 30 | 21 | 61.0 | 1 Hr | Valid |
4342 | Beijing | 6/30/2017 22:00 | 2017 | 6 | 30 | 22 | 49.0 | 1 Hr | Valid |
4343 | Beijing | 6/30/2017 23:00 | 2017 | 6 | 30 | 23 | 55.0 | 1 Hr | Valid |
74465 rows × 9 columns
bj[bj.duplicated(['Year','Value'])]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
10 | Beijing | 2008-04-09 01:00 | 2008 | 4 | 9 | 1 | 64.0 | 1 Hr | Valid |
15 | Beijing | 2008-04-09 06:00 | 2008 | 4 | 9 | 6 | 69.0 | 1 Hr | Valid |
16 | Beijing | 2008-04-09 07:00 | 2008 | 4 | 9 | 7 | 69.0 | 1 Hr | Valid |
17 | Beijing | 2008-04-09 08:00 | 2008 | 4 | 9 | 8 | 64.0 | 1 Hr | Valid |
18 | Beijing | 2008-04-09 09:00 | 2008 | 4 | 9 | 9 | 69.0 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4339 | Beijing | 6/30/2017 19:00 | 2017 | 6 | 30 | 19 | 51.0 | 1 Hr | Valid |
4340 | Beijing | 6/30/2017 20:00 | 2017 | 6 | 30 | 20 | 68.0 | 1 Hr | Valid |
4341 | Beijing | 6/30/2017 21:00 | 2017 | 6 | 30 | 21 | 61.0 | 1 Hr | Valid |
4342 | Beijing | 6/30/2017 22:00 | 2017 | 6 | 30 | 22 | 49.0 | 1 Hr | Valid |
4343 | Beijing | 6/30/2017 23:00 | 2017 | 6 | 30 | 23 | 55.0 | 1 Hr | Valid |
70794 rows × 9 columns
2.处理日期时间变量
2.1建立Timestamp类和Period类
Timestamp对象 多种格式都可以转化
from datetime import datetime # 从datetime包中引入datetime
datetime(2012, 5, 1)
datetime.datetime(2012, 5, 1, 0, 0)
pd.Timestamp(datetime(2012, 5, 1))
Timestamp('2012-05-01 00:00:00')
pd.Timestamp(datetime(2012, 5, 1, 1, 2, 3))
Timestamp('2012-05-01 01:02:03')
pd.Timestamp('2012-05-01 1:2:3')
Timestamp('2012-05-01 01:02:03')
pd.Timestamp(2012, 5, 1)
Timestamp('2012-05-01 00:00:00')
Peroid对象
可以被看作是简化之后的Timestamp对象
由于详细数据的不完整,而表示的是一段时间,而不是一个时点
但是实际使用中很可能是按照时点在使用
很多使用方法和Timestamp相同,因此不再详细介绍
freq是指数值的频率
pd.Period('2011-01')
Period('2011-01', 'M')
pd.Period('2012-05', freq='D')
Period('2012-05-01', 'D')
2.2将数据转换为Timestamp类
使用pd.Timestamp()直接转换
Timestamp只能针对某个数据转换,若想整列需要使用apply
pd.Timestamp(bj08['Date (LST)'][0])
Timestamp('2008-04-08 15:00:00')
bj08['Date (LST)'].apply(pd.Timestamp)
0 2008-04-08 15:00:00
1 2008-04-08 16:00:00
2 2008-04-08 17:00:00
3 2008-04-08 18:00:00
4 2008-04-08 19:00:00
...
5082 2008-11-06 09:00:00
5083 2008-11-06 10:00:00
5084 2008-11-06 11:00:00
5085 2008-11-06 12:00:00
5086 2008-11-06 13:00:00
Name: Date (LST), Length: 5087, dtype: datetime64[ns]
用to_datetime进行批量转换,注意特点“批量”
pd.to_datetime(
arg : 需要转换为Timestamp类的数值(integer, float, string, datetime, list, tuple, 1-d array,Series)
errors = ‘raise’ : {‘ignore’, ‘raise’, ‘coerce’}
(‘raise’, 抛出错误
‘coerce’, 设定为 NaT
‘ignore’, 返回原值)
短日期的解释方式:类似"10/11/12"这样的数据如何解释
dayfirst = ‘False’ : 数值是否day在前
yearfirst = ‘False’ : 数值是否year在前,该设定优先
box = True : 是否返回为DatetimeIndex,False时返回ndarray数组
format = None : 需要转换的字符串格式设定
)
pd.to_datetime(datetime(2012, 5, 1, 1, 2, 3))
Timestamp('2012-05-01 01:02:03')
pd.to_datetime('2012-05-01 1:2:3')
Timestamp('2012-05-01 01:02:03')
pd.to_datetime(['2005/11/23', '2010.12.31'])
DatetimeIndex(['2005-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)
pd.to_datetime(bj08['Date (LST)'], format = "%Y-%m-%d %H:%M")
#如果格式恰当,format可以不写
0 2008-04-08 15:00:00
1 2008-04-08 16:00:00
2 2008-04-08 17:00:00
3 2008-04-08 18:00:00
4 2008-04-08 19:00:00
...
5082 2008-11-06 09:00:00
5083 2008-11-06 10:00:00
5084 2008-11-06 11:00:00
5085 2008-11-06 12:00:00
5086 2008-11-06 13:00:00
Name: Date (LST), Length: 5087, dtype: datetime64[ns]
基于所需的变量列合成Timestamp类
pd.to_datetime(bj08[['Year', 'Month', 'Day', 'Hour']])
0 2008-04-08 15:00:00
1 2008-04-08 16:00:00
2 2008-04-08 17:00:00
3 2008-04-08 18:00:00
4 2008-04-08 19:00:00
...
5082 2008-11-06 09:00:00
5083 2008-11-06 10:00:00
5084 2008-11-06 11:00:00
5085 2008-11-06 12:00:00
5086 2008-11-06 13:00:00
Length: 5087, dtype: datetime64[ns]
2.3使用DatetimeIndex类
DatetimeIndex类对象除了拥有Index类对象的所有功能外,还针对日期时间的特点有如下增强:
1.基于日期时间的各个层级做快速索引操作
2. 快速提取所需的时间层级
3. 按照所指定的时间范围做快速切片
建立DatetimeIndex对象
建立索引时自动转换,set_index 默认原来索引的列是删除的,对于时间这个原来的会保留
使用Timestamp对象建立索引,将会自动转换为DatetimeIndex对象
bj08idx = bj08.set_index(pd.to_datetime(bj08['Date (LST)']))
print(type(bj08idx.index))
bj08idx
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-04-08 15:00:00 | Beijing | 2008-04-08 15:00 | 2008 | 4 | 8 | 15 | 207 | 1 Hr | Valid |
2008-04-08 16:00:00 | Beijing | 2008-04-08 16:00 | 2008 | 4 | 8 | 16 | 180 | 1 Hr | Valid |
2008-04-08 17:00:00 | Beijing | 2008-04-08 17:00 | 2008 | 4 | 8 | 17 | 152 | 1 Hr | Valid |
2008-04-08 18:00:00 | Beijing | 2008-04-08 18:00 | 2008 | 4 | 8 | 18 | 162 | 1 Hr | Valid |
2008-04-08 19:00:00 | Beijing | 2008-04-08 19:00 | 2008 | 4 | 8 | 19 | 171 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-06 09:00:00 | Beijing | 2008-11-06 09:00 | 2008 | 11 | 6 | 9 | 42 | 1 Hr | Valid |
2008-11-06 10:00:00 | Beijing | 2008-11-06 10:00 | 2008 | 11 | 6 | 10 | 46 | 1 Hr | Valid |
2008-11-06 11:00:00 | Beijing | 2008-11-06 11:00 | 2008 | 11 | 6 | 11 | 40 | 1 Hr | Valid |
2008-11-06 12:00:00 | Beijing | 2008-11-06 12:00 | 2008 | 11 | 6 | 12 | 35 | 1 Hr | Valid |
2008-11-06 13:00:00 | Beijing | 2008-11-06 13:00 | 2008 | 11 | 6 | 13 | 19 | 1 Hr | Valid |
5087 rows × 9 columns
使用date_range建立DatetimeIndex对象
这种建立方式主要是和reindx命令配合使用,以快速完成对时间序列中缺失值的填充工作
pd.date_range(
start /end = None : 日期时间范围的起点/终点,均为类日期时间格式的字符串/数据
periods = None : 准备生成的总记录数
freq = ‘D’ : 生成记录时的时间周期,可以使用字母和数值倍数的组合,如’5H’
name = None : 生成的DatetimeIndex对象的名称
)
pd.bdate_range(
主要参数和pd.date_range几乎完全相同,但默认freq = ‘B’ (business daily)
另外附加了几个针对工作日/休息日筛选的参数
)
pd.date_range('1/1/2012', periods=5)
DatetimeIndex(['2012-01-01', '2012-01-02', '2012-01-03', '2012-01-04',
'2012-01-05'],
dtype='datetime64[ns]', freq='D')
pd.date_range('1/1/2012', periods=5, freq='M')
DatetimeIndex(['2012-01-31', '2012-02-29', '2012-03-31', '2012-04-30',
'2012-05-31'],
dtype='datetime64[ns]', freq='M')
基于索引的快速切片操作
bj08idx["2008-11-1":"2008-11-5"]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-11-01 00:00:00 | Beijing | 2008-11-01 00:00 | 2008 | 11 | 1 | 0 | 97 | 1 Hr | Valid |
2008-11-01 01:00:00 | Beijing | 2008-11-01 01:00 | 2008 | 11 | 1 | 1 | 107 | 1 Hr | Valid |
2008-11-01 02:00:00 | Beijing | 2008-11-01 02:00 | 2008 | 11 | 1 | 2 | 118 | 1 Hr | Valid |
2008-11-01 03:00:00 | Beijing | 2008-11-01 03:00 | 2008 | 11 | 1 | 3 | 120 | 1 Hr | Valid |
2008-11-01 04:00:00 | Beijing | 2008-11-01 04:00 | 2008 | 11 | 1 | 4 | 116 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-05 19:00:00 | Beijing | 2008-11-05 19:00 | 2008 | 11 | 5 | 19 | 174 | 1 Hr | Valid |
2008-11-05 20:00:00 | Beijing | 2008-11-05 20:00 | 2008 | 11 | 5 | 20 | 195 | 1 Hr | Valid |
2008-11-05 21:00:00 | Beijing | 2008-11-05 21:00 | 2008 | 11 | 5 | 21 | 203 | 1 Hr | Valid |
2008-11-05 22:00:00 | Beijing | 2008-11-05 22:00 | 2008 | 11 | 5 | 22 | 214 | 1 Hr | Valid |
2008-11-05 23:00:00 | Beijing | 2008-11-05 23:00 | 2008 | 11 | 5 | 23 | 214 | 1 Hr | Valid |
120 rows × 9 columns
bj08idx["2008-11"]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-11-01 00:00:00 | Beijing | 2008-11-01 00:00 | 2008 | 11 | 1 | 0 | 97 | 1 Hr | Valid |
2008-11-01 01:00:00 | Beijing | 2008-11-01 01:00 | 2008 | 11 | 1 | 1 | 107 | 1 Hr | Valid |
2008-11-01 02:00:00 | Beijing | 2008-11-01 02:00 | 2008 | 11 | 1 | 2 | 118 | 1 Hr | Valid |
2008-11-01 03:00:00 | Beijing | 2008-11-01 03:00 | 2008 | 11 | 1 | 3 | 120 | 1 Hr | Valid |
2008-11-01 04:00:00 | Beijing | 2008-11-01 04:00 | 2008 | 11 | 1 | 4 | 116 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-06 09:00:00 | Beijing | 2008-11-06 09:00 | 2008 | 11 | 6 | 9 | 42 | 1 Hr | Valid |
2008-11-06 10:00:00 | Beijing | 2008-11-06 10:00 | 2008 | 11 | 6 | 10 | 46 | 1 Hr | Valid |
2008-11-06 11:00:00 | Beijing | 2008-11-06 11:00 | 2008 | 11 | 6 | 11 | 40 | 1 Hr | Valid |
2008-11-06 12:00:00 | Beijing | 2008-11-06 12:00 | 2008 | 11 | 6 | 12 | 35 | 1 Hr | Valid |
2008-11-06 13:00:00 | Beijing | 2008-11-06 13:00 | 2008 | 11 | 6 | 13 | 19 | 1 Hr | Valid |
134 rows × 9 columns
bj08idx["2008-11-1":"2008-11-5 9:00:00"]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-11-01 00:00:00 | Beijing | 2008-11-01 00:00 | 2008 | 11 | 1 | 0 | 97 | 1 Hr | Valid |
2008-11-01 01:00:00 | Beijing | 2008-11-01 01:00 | 2008 | 11 | 1 | 1 | 107 | 1 Hr | Valid |
2008-11-01 02:00:00 | Beijing | 2008-11-01 02:00 | 2008 | 11 | 1 | 2 | 118 | 1 Hr | Valid |
2008-11-01 03:00:00 | Beijing | 2008-11-01 03:00 | 2008 | 11 | 1 | 3 | 120 | 1 Hr | Valid |
2008-11-01 04:00:00 | Beijing | 2008-11-01 04:00 | 2008 | 11 | 1 | 4 | 116 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-05 05:00:00 | Beijing | 2008-11-05 05:00 | 2008 | 11 | 5 | 5 | 131 | 1 Hr | Valid |
2008-11-05 06:00:00 | Beijing | 2008-11-05 06:00 | 2008 | 11 | 5 | 6 | 129 | 1 Hr | Valid |
2008-11-05 07:00:00 | Beijing | 2008-11-05 07:00 | 2008 | 11 | 5 | 7 | 136 | 1 Hr | Valid |
2008-11-05 08:00:00 | Beijing | 2008-11-05 08:00 | 2008 | 11 | 5 | 8 | 144 | 1 Hr | Valid |
2008-11-05 09:00:00 | Beijing | 2008-11-05 09:00 | 2008 | 11 | 5 | 9 | 143 | 1 Hr | Valid |
106 rows × 9 columns
2.4 对时间序列做基本处理
2.4.1 序列的分组汇总
直接取出索引的相应层级
DatetimeIndex对象可直接引用的Attributes:
date : Returns numpy array of python datetime.date objects
time : Returns numpy array of datetime.time
year : The year of the datetime
quarter : The quarter of the date
month : The month as January=1, December=12
week : The week ordinal of the year
weekday : The day of the week with Monday=0, Sunday=6
weekday_name : The name of day in a week (ex: Friday)
weekofyear : The week ordinal of the year
day : The days of the datetime
dayofweek : The day of the week with Monday=0, Sunday=6
dayofyear : The ordinal day of the year
days_in_month : The number of days in the month
daysinmonth : The number of days in the month
hour : The hours of the datetime
minute : The minutes of the datetime
second : The seconds of the datetime
microsecond : The microseconds of the datetime
nanosecond : The nanoseconds of the datetime
is_leap_year : if the date belongs to a leap year
is_month_end : if last day of month (defined by frequency)
is_month_start : if first day of month (defined by frequency)
is_quarter_end : if last day of quarter (defined by frequency)
is_quarter_start : if first day of quarter (defined by frequency)
is_year_end : if last day of year (defined by frequency)
is_year_start : if first day of year (defined by frequency)
bj08idx.index.hour
Int64Index([15, 16, 17, 18, 19, 20, 21, 22, 23, 0,
...
4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
dtype='int64', name='Date (LST)', length=5087)
直接使用groupby方法进行汇总
bj08idx.groupby(bj08idx.index.month).max()#意义不大,最好指定某一列的最大值
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
4 | Beijing | 2008-04-30 23:00 | 2008 | 4 | 30 | 23 | 610 | 1 Hr | Valid |
5 | Beijing | 2008-05-31 23:00 | 2008 | 5 | 31 | 23 | 405 | 1 Hr | Valid |
6 | Beijing | 2008-06-30 23:00 | 2008 | 6 | 30 | 23 | 270 | 1 Hr | Valid |
7 | Beijing | 2008-07-31 23:00 | 2008 | 7 | 31 | 23 | 272 | 1 Hr | Valid |
8 | Beijing | 2008-08-31 23:00 | 2008 | 8 | 31 | 23 | 195 | 1 Hr | Valid |
9 | Beijing | 2008-09-30 23:00 | 2008 | 9 | 30 | 23 | 226 | 1 Hr | Valid |
10 | Beijing | 2008-10-31 23:00 | 2008 | 10 | 31 | 23 | 415 | 1 Hr | Valid |
11 | Beijing | 2008-11-06 13:00 | 2008 | 11 | 6 | 23 | 214 | 1 Hr | Valid |
使用功能更强的resample函数
df.resample()
使用上比groupby更简单(输入更简洁)
可以将数值和汇总单位进行组合,实现更复杂的汇总计算
bj08idx.resample('3D').mean()
Year | Month | Day | Hour | Value | |
---|---|---|---|---|---|
Date (LST) | |||||
2008-04-08 | 2008.0 | 4.0 | 9.263158 | 12.684211 | 93.754386 |
2008-04-11 | 2008.0 | 4.0 | 12.000000 | 11.500000 | 67.791667 |
2008-04-14 | 2008.0 | 4.0 | 15.000000 | 11.500000 | 164.527778 |
2008-04-17 | 2008.0 | 4.0 | 18.000000 | 11.500000 | 163.166667 |
2008-04-20 | 2008.0 | 4.0 | 21.000000 | 11.500000 | 38.597222 |
... | ... | ... | ... | ... | ... |
2008-10-23 | 2008.0 | 10.0 | 24.000000 | 11.500000 | 17.902778 |
2008-10-26 | 2008.0 | 10.0 | 27.000000 | 11.500000 | 27.694444 |
2008-10-29 | 2008.0 | 10.0 | 30.000000 | 11.500000 | 56.861111 |
2008-11-01 | 2008.0 | 11.0 | 2.000000 | 11.500000 | 38.583333 |
2008-11-04 | 2008.0 | 11.0 | 4.838710 | 10.370968 | 113.225806 |
71 rows × 5 columns
2.4.2 序列的缺失值处理
时间序列要求记录的时间点连贯无缺失,因此需要:
首先建立针对整个时间范围的完整序列框架
随后针对无数据的时间点进行缺失值处理
df.reindex()是完成该任务的强有力工具
bj09idx = bj09.set_index(pd.to_datetime(bj09['Date (LST)']))
bj09idx = bj09idx[bj09idx.Value > 0]
bj09idx#从17号开始,说明之前是缺失值
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2009-02-17 17:00:00 | Beijing | 2009-02-17 17:00 | 2009 | 2 | 17 | 17 | 70 | 1 Hr | Valid |
2009-02-17 18:00:00 | Beijing | 2009-02-17 18:00 | 2009 | 2 | 17 | 18 | 57 | 1 Hr | Valid |
2009-02-17 19:00:00 | Beijing | 2009-02-17 19:00 | 2009 | 2 | 17 | 19 | 58 | 1 Hr | Valid |
2009-02-17 20:00:00 | Beijing | 2009-02-17 20:00 | 2009 | 2 | 17 | 20 | 63 | 1 Hr | Valid |
2009-02-17 21:00:00 | Beijing | 2009-02-17 21:00 | 2009 | 2 | 17 | 21 | 61 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2009-12-31 18:00:00 | Beijing | 2009-12-31 18:00 | 2009 | 12 | 31 | 18 | 64 | 1 Hr | Valid |
2009-12-31 19:00:00 | Beijing | 2009-12-31 19:00 | 2009 | 12 | 31 | 19 | 77 | 1 Hr | Valid |
2009-12-31 20:00:00 | Beijing | 2009-12-31 20:00 | 2009 | 12 | 31 | 20 | 120 | 1 Hr | Valid |
2009-12-31 21:00:00 | Beijing | 2009-12-31 21:00 | 2009 | 12 | 31 | 21 | 163 | 1 Hr | Valid |
2009-12-31 22:00:00 | Beijing | 2009-12-31 22:00 | 2009 | 12 | 31 | 22 | 167 | 1 Hr | Valid |
6779 rows × 9 columns
idx = pd.date_range(start = '2009-02-01 00:00:00',
end = '2009-12-31 23:00:00', freq='H')
idx
DatetimeIndex(['2009-02-01 00:00:00', '2009-02-01 01:00:00',
'2009-02-01 02:00:00', '2009-02-01 03:00:00',
'2009-02-01 04:00:00', '2009-02-01 05:00:00',
'2009-02-01 06:00:00', '2009-02-01 07:00:00',
'2009-02-01 08:00:00', '2009-02-01 09:00:00',
...
'2009-12-31 14:00:00', '2009-12-31 15:00:00',
'2009-12-31 16:00:00', '2009-12-31 17:00:00',
'2009-12-31 18:00:00', '2009-12-31 19:00:00',
'2009-12-31 20:00:00', '2009-12-31 21:00:00',
'2009-12-31 22:00:00', '2009-12-31 23:00:00'],
dtype='datetime64[ns]', length=8016, freq='H')
bj09idx.reindex(idx)#会报错,因为源数据中有重复值
bj09idx[bj09idx.index.duplicated()]
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2009-03-08 03:00:00 | Beijing | 2009-03-08 03:00 | 2009 | 3 | 8 | 3 | 179 | 1 Hr | Valid |
bj09idx['2009-03-08']
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2009-03-08 00:00:00 | Beijing | 2009-03-08 00:00 | 2009 | 3 | 8 | 0 | 204 | 1 Hr | Valid |
2009-03-08 01:00:00 | Beijing | 2009-03-08 01:00 | 2009 | 3 | 8 | 1 | 189 | 1 Hr | Valid |
2009-03-08 03:00:00 | Beijing | 2009-03-08 03:00 | 2009 | 3 | 8 | 3 | 195 | 1 Hr | Valid |
2009-03-08 03:00:00 | Beijing | 2009-03-08 03:00 | 2009 | 3 | 8 | 3 | 179 | 1 Hr | Valid |
2009-03-08 04:00:00 | Beijing | 2009-03-08 04:00 | 2009 | 3 | 8 | 4 | 188 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2009-03-08 19:00:00 | Beijing | 2009-03-08 19:00 | 2009 | 3 | 8 | 19 | 77 | 1 Hr | Valid |
2009-03-08 20:00:00 | Beijing | 2009-03-08 20:00 | 2009 | 3 | 8 | 20 | 71 | 1 Hr | Valid |
2009-03-08 21:00:00 | Beijing | 2009-03-08 21:00 | 2009 | 3 | 8 | 21 | 86 | 1 Hr | Valid |
2009-03-08 22:00:00 | Beijing | 2009-03-08 22:00 | 2009 | 3 | 8 | 22 | 41 | 1 Hr | Valid |
2009-03-08 23:00:00 | Beijing | 2009-03-08 23:00 | 2009 | 3 | 8 | 23 | 14 | 1 Hr | Valid |
24 rows × 9 columns
bj09idx[~bj09idx.index.duplicated()].reindex(idx)
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
2009-02-01 00:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2009-02-01 01:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2009-02-01 02:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2009-02-01 03:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2009-02-01 04:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2009-12-31 19:00:00 | Beijing | 2009-12-31 19:00 | 2009.0 | 12.0 | 31.0 | 19.0 | 77.0 | 1 Hr | Valid |
2009-12-31 20:00:00 | Beijing | 2009-12-31 20:00 | 2009.0 | 12.0 | 31.0 | 20.0 | 120.0 | 1 Hr | Valid |
2009-12-31 21:00:00 | Beijing | 2009-12-31 21:00 | 2009.0 | 12.0 | 31.0 | 21.0 | 163.0 | 1 Hr | Valid |
2009-12-31 22:00:00 | Beijing | 2009-12-31 22:00 | 2009.0 | 12.0 | 31.0 | 22.0 | 167.0 | 1 Hr | Valid |
2009-12-31 23:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
8016 rows × 9 columns
bj09idx[~bj09idx.index.duplicated()].reindex(idx, method = 'bfill')
#用临近数值填充
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
2009-02-01 00:00:00 | Beijing | 2009-02-17 17:00 | 2009.0 | 2.0 | 17.0 | 17.0 | 70.0 | 1 Hr | Valid |
2009-02-01 01:00:00 | Beijing | 2009-02-17 17:00 | 2009.0 | 2.0 | 17.0 | 17.0 | 70.0 | 1 Hr | Valid |
2009-02-01 02:00:00 | Beijing | 2009-02-17 17:00 | 2009.0 | 2.0 | 17.0 | 17.0 | 70.0 | 1 Hr | Valid |
2009-02-01 03:00:00 | Beijing | 2009-02-17 17:00 | 2009.0 | 2.0 | 17.0 | 17.0 | 70.0 | 1 Hr | Valid |
2009-02-01 04:00:00 | Beijing | 2009-02-17 17:00 | 2009.0 | 2.0 | 17.0 | 17.0 | 70.0 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2009-12-31 19:00:00 | Beijing | 2009-12-31 19:00 | 2009.0 | 12.0 | 31.0 | 19.0 | 77.0 | 1 Hr | Valid |
2009-12-31 20:00:00 | Beijing | 2009-12-31 20:00 | 2009.0 | 12.0 | 31.0 | 20.0 | 120.0 | 1 Hr | Valid |
2009-12-31 21:00:00 | Beijing | 2009-12-31 21:00 | 2009.0 | 12.0 | 31.0 | 21.0 | 163.0 | 1 Hr | Valid |
2009-12-31 22:00:00 | Beijing | 2009-12-31 22:00 | 2009.0 | 12.0 | 31.0 | 22.0 | 167.0 | 1 Hr | Valid |
2009-12-31 23:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
8016 rows × 9 columns
序列数值平移
df.shift(
periods = 1 : 希望移动的周期数
freq : 时间频度字符串
axis = 0
)
bj08idx.shift(3)
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-04-08 15:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2008-04-08 16:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2008-04-08 17:00:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2008-04-08 18:00:00 | Beijing | 2008-04-08 15:00 | 2008.0 | 4.0 | 8.0 | 15.0 | 207.0 | 1 Hr | Valid |
2008-04-08 19:00:00 | Beijing | 2008-04-08 16:00 | 2008.0 | 4.0 | 8.0 | 16.0 | 180.0 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-06 09:00:00 | Beijing | 2008-11-06 06:00 | 2008.0 | 11.0 | 6.0 | 6.0 | 33.0 | 1 Hr | Valid |
2008-11-06 10:00:00 | Beijing | 2008-11-06 07:00 | 2008.0 | 11.0 | 6.0 | 7.0 | 31.0 | 1 Hr | Valid |
2008-11-06 11:00:00 | Beijing | 2008-11-06 08:00 | 2008.0 | 11.0 | 6.0 | 8.0 | 42.0 | 1 Hr | Valid |
2008-11-06 12:00:00 | Beijing | 2008-11-06 09:00 | 2008.0 | 11.0 | 6.0 | 9.0 | 42.0 | 1 Hr | Valid |
2008-11-06 13:00:00 | Beijing | 2008-11-06 10:00 | 2008.0 | 11.0 | 6.0 | 10.0 | 46.0 | 1 Hr | Valid |
5087 rows × 9 columns
实战:建立时间索引
bj08idx = bj08.set_index(pd.to_datetime(bj08['Date (LST)']))
bj08idx
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
Date (LST) | |||||||||
2008-04-08 15:00:00 | Beijing | 2008-04-08 15:00 | 2008 | 4 | 8 | 15 | 207 | 1 Hr | Valid |
2008-04-08 16:00:00 | Beijing | 2008-04-08 16:00 | 2008 | 4 | 8 | 16 | 180 | 1 Hr | Valid |
2008-04-08 17:00:00 | Beijing | 2008-04-08 17:00 | 2008 | 4 | 8 | 17 | 152 | 1 Hr | Valid |
2008-04-08 18:00:00 | Beijing | 2008-04-08 18:00 | 2008 | 4 | 8 | 18 | 162 | 1 Hr | Valid |
2008-04-08 19:00:00 | Beijing | 2008-04-08 19:00 | 2008 | 4 | 8 | 19 | 171 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-06 09:00:00 | Beijing | 2008-11-06 09:00 | 2008 | 11 | 6 | 9 | 42 | 1 Hr | Valid |
2008-11-06 10:00:00 | Beijing | 2008-11-06 10:00 | 2008 | 11 | 6 | 10 | 46 | 1 Hr | Valid |
2008-11-06 11:00:00 | Beijing | 2008-11-06 11:00 | 2008 | 11 | 6 | 11 | 40 | 1 Hr | Valid |
2008-11-06 12:00:00 | Beijing | 2008-11-06 12:00 | 2008 | 11 | 6 | 12 | 35 | 1 Hr | Valid |
2008-11-06 13:00:00 | Beijing | 2008-11-06 13:00 | 2008 | 11 | 6 | 13 | 19 | 1 Hr | Valid |
5087 rows × 9 columns
bj08idx = bj08.set_index(pd.to_datetime(bj08[['Year','Month','Day','Hour']]))
bj08idx
Site | Date (LST) | Year | Month | Day | Hour | Value | Duration | QC Name | |
---|---|---|---|---|---|---|---|---|---|
2008-04-08 15:00:00 | Beijing | 2008-04-08 15:00 | 2008 | 4 | 8 | 15 | 207 | 1 Hr | Valid |
2008-04-08 16:00:00 | Beijing | 2008-04-08 16:00 | 2008 | 4 | 8 | 16 | 180 | 1 Hr | Valid |
2008-04-08 17:00:00 | Beijing | 2008-04-08 17:00 | 2008 | 4 | 8 | 17 | 152 | 1 Hr | Valid |
2008-04-08 18:00:00 | Beijing | 2008-04-08 18:00 | 2008 | 4 | 8 | 18 | 162 | 1 Hr | Valid |
2008-04-08 19:00:00 | Beijing | 2008-04-08 19:00 | 2008 | 4 | 8 | 19 | 171 | 1 Hr | Valid |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2008-11-06 09:00:00 | Beijing | 2008-11-06 09:00 | 2008 | 11 | 6 | 9 | 42 | 1 Hr | Valid |
2008-11-06 10:00:00 | Beijing | 2008-11-06 10:00 | 2008 | 11 | 6 | 10 | 46 | 1 Hr | Valid |
2008-11-06 11:00:00 | Beijing | 2008-11-06 11:00 | 2008 | 11 | 6 | 11 | 40 | 1 Hr | Valid |
2008-11-06 12:00:00 | Beijing | 2008-11-06 12:00 | 2008 | 11 | 6 | 12 | 35 | 1 Hr | Valid |
2008-11-06 13:00:00 | Beijing | 2008-11-06 13:00 | 2008 | 11 | 6 | 13 | 19 | 1 Hr | Valid |
5087 rows × 9 columns
from datetime import datetime
bj08idx = bj08idx[bj08idx.Value > 0]#去掉-999缺失值
bj08idx.groupby(bj08idx.index.month).Value.mean()
4 103.897579
5 98.406504
6 99.794444
7 89.735945
8 65.361111
9 59.312224
10 84.249326
11 73.119403
Name: Value, dtype: float64
计算大于200,方法一
bj08idx[bj08idx.Value>200].drop_duplicates(['Day']).Day.count()
26
计算大于200,方法二
bj08idx[bj08idx.Value>200].Day.nunique()#nuique计算非重复数值的个数
26
3.数据的图形展示
3.1 配置绘图系统环境
# 图形在Pandas页面同步显示的问题
%matplotlib inline
# 绘图功能的进一步美化和功能增强包,参考http://seaborn.pydata.org/
import seaborn
seaborn.set_style("whitegrid")
# 注意有中文兼容问题,需要重新导入中文设定
# 中文字符兼容问题
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
# 进一步在一些细节上的美化和优化
import matplotlib.pyplot as plt
plt.figure()
df2['总分'].plot.box(title='总分的箱图分布', ylim=(60, 80))
<AxesSubplot:title={'center':'总分的箱图分布'}>
3.2 绘图命令基本框架
df.plot(
绘图用数据
data : 数据框
x = None: 行变量的名称/顺序号
y = None : 列变量的名称/顺序号
kind = ‘line’ : 需要绘制的图形种类
‘line’ : line plot (default)
‘bar’ : vertical bar plot #条图
‘barh’ : horizontal bar plot #水平的条图
‘hist’ : histogram #折方图
‘box’ : boxplot
‘kde’ : Kernel Density Estimation plot #密度图
‘density’ : same as ‘kde’
‘area’ : area plot
‘pie’ : pie plot #饼图
‘scatter’ : scatter plot #散点图
‘hexbin’ : hexbin plot
各种辅助命令
figsize : a tuple (width, height) in inches
xlim / ylim : X/Y轴的取值范围,2-tuple/list格式
logx / logy / loglog = False : 对X/Y/双轴同时使用对数尺度
title : string or list
Alpha : 图形透明度,0-1
图组命令
subplots = False : 是否分图组绘制图形
sharex : 是否使用相同的X坐标
ax = None时,取值为True,否则取值为False
sharey = False : 是否使用相同的Y坐标
ax = None : 需要叠加的 matplotlib绘图对象
)
图形种类的等价写法
df.plot.kind()
df2['总分'].plot.box(title='总分的箱图分布', ylim=(60, 80))
# 考察过去一段时间的数据分布
bj08[-100:].Value.plot(figsize=(12,8))
bj.groupby(bj.Year).Value.plot() # 有无seaborn修饰时的结果不同
条图
需要先自行完成数据汇总,绘图函数只能完成绘图工作
简单条图
# 条图
pd.value_counts(df2.类型).plot.bar()
pd.value_counts(df2.类型).plot.barh()
复式条图
行索引构成大分组,变量列构成小分组
import numpy as np
dfnew = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
print(dfnew)
dfnew.plot.bar()
分段条图
plot.bar(stacked = True)
dfnew.plot.bar(stacked = True)
直方图
简单直方图
plot.hist(
by : 在df中用于分组的变量列(绘制为图组)
bins = 10 : 需要拆分的组数
)
#直方图
df2.总分.plot.hist(bins=30)
直方图图组
hist(
by : 在df中用于分组的变量列(绘制为图组)
)
df2.总分.hist(by = df2.类型, bins=10)
饼图
注意是每行代表一个饼块的数据结构,因此需要先自行汇总好变量频数
plot.pie(
y : 指定需要绘制的变量列名称
subplots = False : 多个变量列时要求分组绘图
Labels
Colors
)
简单饼图
df2.类型.value_counts().plot.pie()
pd.value_counts(df2.类型).plot.pie()#和上面的是等价的
df2.loc[:9,['名次','总分']].plot.pie(subplots = True, figsize=(8, 4))
Semicircle 半饼图
当数值总和小于1时,绘制的是semicircle
pd.Series([0.1,0.2,0.1,0.3]
, index=['a', 'b', 'c', 'd']).plot.pie(figsize=(6, 6))
箱图 针对连续变量
plot.box(
vert = True : 是否纵向绘图
)
boxplot(
by : 在df中用于分组的变量列(绘制为图组)
)
df2.plot.box(vert = False) #显示出能显示的连续变量
df2.boxplot(by='类型')
散点图
plot.scatter(
默认变量x轴的变量名和y轴的变量名
s : 控制散点大小的变量列,不能使用df中的简写方式指定
c : 控制散点颜色的变量列
)
简单散点图
df2.plot.scatter('总分', '名次')
df2.plot.scatter(x= '总分', y='名次', c='名次')
df2.plot.scatter(x= '总分', y='名次', s=df2.名次)
#s不能写成加引号的变量名
重叠散点图
使用matplotlib的ax对象进行图形叠加
ax = df.plot.scatter(x=‘’, y=‘’, color=‘’, label=‘’);
df.plot.scatter(x=‘’, y=‘’, color=‘’, label=‘’, ax=ax);
ax = df2.plot.scatter(x='总分', y='名次'
, color='DarkBlue', label='Group 1');
df2.plot.scatter(x='名次', y='总分'
, color='DarkGreen', label='Group 2', ax = ax);
实战:图形探索PM2.5数据
基于前面数据整理实战中的成果,要求:
绘制分年度的PM2.5箱图(所有箱体在一张图上)
分图组绘制PM2.5的直方图
绘制一天24小时PM2.5均值变化的线图
各年比较的PM2.5最大值超过100、200、300、500的天数的分段条图
bj.boxplot(by='Year')
bj.Value.hist(by = bj.Year, bins=20)
bjg= bj.groupby('Hour')
bjg['Value'].mean().plot()
bj.plot.scatter('Hour', 'Value')
pd.value_counts(bj[bj.Value>200].Year).plot.bar()