pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理

注:学习笔记基于文彤老师的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

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))

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第1张图片

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))

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第2张图片

# 考察过去一段时间的数据分布
bj08[-100:].Value.plot(figsize=(12,8))

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第3张图片

bj.groupby(bj.Year).Value.plot() # 有无seaborn修饰时的结果不同

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第4张图片

条图

需要先自行完成数据汇总,绘图函数只能完成绘图工作

简单条图

# 条图
pd.value_counts(df2.类型).plot.bar()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第5张图片

pd.value_counts(df2.类型).plot.barh()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第6张图片

复式条图

行索引构成大分组,变量列构成小分组

import numpy as np
dfnew = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
print(dfnew)
dfnew.plot.bar()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第7张图片

分段条图

plot.bar(stacked = True)

dfnew.plot.bar(stacked = True)

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第8张图片

直方图

简单直方图

plot.hist(

by : 在df中用于分组的变量列(绘制为图组)
bins = 10 : 需要拆分的组数
)

#直方图
df2.总分.plot.hist(bins=30)

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第9张图片

直方图图组

hist(

by : 在df中用于分组的变量列(绘制为图组)
)

df2.总分.hist(by = df2.类型, bins=10)

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第10张图片

饼图

注意是每行代表一个饼块的数据结构,因此需要先自行汇总好变量频数

plot.pie(

y : 指定需要绘制的变量列名称
subplots = False : 多个变量列时要求分组绘图
Labels
Colors
)

简单饼图

df2.类型.value_counts().plot.pie()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第11张图片

pd.value_counts(df2.类型).plot.pie()#和上面的是等价的
df2.loc[:9,['名次','总分']].plot.pie(subplots = True, figsize=(8, 4))

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第12张图片

Semicircle 半饼图

当数值总和小于1时,绘制的是semicircle

pd.Series([0.1,0.2,0.1,0.3]
          , index=['a', 'b', 'c', 'd']).plot.pie(figsize=(6, 6))

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第13张图片

箱图 针对连续变量

plot.box(

vert = True : 是否纵向绘图
)

boxplot(

by : 在df中用于分组的变量列(绘制为图组)
)

df2.plot.box(vert = False) #显示出能显示的连续变量  

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第14张图片

df2.boxplot(by='类型')

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第15张图片

散点图

plot.scatter(

默认变量x轴的变量名和y轴的变量名
s : 控制散点大小的变量列,不能使用df中的简写方式指定
c : 控制散点颜色的变量列
)

简单散点图

df2.plot.scatter('总分', '名次')

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第16张图片

df2.plot.scatter(x= '总分', y='名次', c='名次')

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第17张图片

df2.plot.scatter(x= '总分', y='名次', s=df2.名次)
 #s不能写成加引号的变量名

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第18张图片

重叠散点图

使用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);

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第19张图片

实战:图形探索PM2.5数据

基于前面数据整理实战中的成果,要求:

绘制分年度的PM2.5箱图(所有箱体在一张图上)
分图组绘制PM2.5的直方图
绘制一天24小时PM2.5均值变化的线图
各年比较的PM2.5最大值超过100、200、300、500的天数的分段条图

bj.boxplot(by='Year')

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第20张图片

bj.Value.hist(by = bj.Year, bins=20)

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第21张图片

bjg= bj.groupby('Hour')
bjg['Value'].mean().plot()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第22张图片

bj.plot.scatter('Hour', 'Value')

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第23张图片

pd.value_counts(bj[bj.Value>200].Year).plot.bar()

pandas学习笔记(四):数据的清洗、绘图以及时间数据的处理_第24张图片

你可能感兴趣的:(python,数据分析,pandas)