pandas实战(PM2.5)
原创
©著作权归作者所有:来自51CTO博客作者BugMaker999的原创作品,请联系作者获取转载授权,否则将追究法律责任
实战内容:利用pandas以及数据可视化对比中美统计的PM2.5数据
首先打印一下数据信息,查看数据结构
= "./BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
print(df.head())
print(df.info())
前5行数据如下:
数据的详细信息如下:
我们将时间数据进行合并,并将得到的新的时间添加到数据中,并将时间设置为索引,以便画图时使用
# 观察数据,我们可以知道csv文件中的时间间隔为一小时,故将采样频率设置为"H"
period = pd.PeriodIndex(year=df["year"], month=df["month"], day=df["day"], hour=df["hour"], freq="H")
df["datetime"] = period
df.set_index("datetime", inplace=True)
现在我们要取得PM_US Post作为y轴数据画图
= df["PM_US Post"]
x = data.index
y = data.values
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(len(x)), y)
plt.show()
画图结果:
emmmm,惨不忍睹,数据太密集了,而且若前半部分数据大部分是NaN,后半部分基本没有NaN,直接dropna会导致时间很不均匀。
现在重新采样,将时间间隔设置为7天(也就是原7*24=148条数据整合成1条数据),同时将这7天的PM2.5数据取平均值作为采样数据
df = df.resample("7D").mean()
直接画图
= data.index
x = [i.strftime("%Y-%m-%d") for i in x]
y = data.values
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(len(x)), y)
plt.xticks(range(0, len(x), 10), list(x)[::10], rotation=45)
plt.show()
降采样后的结果:
我们对比一下中美检测PM2.5,取"PM_Dongsi"作为中国的数据画图
= data_cn.index
x_cn = [i.strftime("%Y-%m-%d") for i in x_cn]
y_cn = data_cn.values
plt.plot(range(len(x_cn)), y_cn, label="CN_POST")
由于中国统计的数据从2010-01-01到2013-01-04全是NaN,所以前半部分没有橙色的线条
完整代码:
import pandas as pd
from matplotlib import pyplot as plt
def main():
file_path = "./BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
# print(df.head(1)[["PM_Dongsi","PM_Dongsihuan"]])
# print(df.info())
# 把分开的时间字符串通过PeriodIndex方法转化为pandas的时间类型
period = pd.PeriodIndex(year=df["year"], month=df["month"], day=df["day"], hour=df["hour"], freq="H")
df["datetime"] = period
# 将datetime设置为索引
df.set_index("datetime", inplace=True)
# 进行降采样
df = df.resample("7D").mean()
data = df["PM_US Post"] # 取出PM_US Post列,然后删除含有NaN的数据
data_cn = df["PM_Dongsi"]
x = data.index
x_cn = data_cn.index
x = [i.strftime("%Y-%m-%d") for i in x]
x_cn = [i.strftime("%Y-%m-%d") for i in x_cn]
y = data.values
y_cn = data_cn.values
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(len(x)), y, label="US_POST")
plt.plot(range(len(x_cn)), y_cn, label="CN_POST")
plt.xticks(range(0, len(x), 10), list(x)[::10], rotation=45)
plt.legend(loc="best")
plt.savefig(fname="./1.png", dpi=500)
plt.show()
if __name__ == '__main__':
main()