python处理数据与数据可视化

应用python绘制全国温湿度表

2020-05-26  本文已影响0人  刘全_c529

开始之前简单交代一下背景,我研究生导师在全国做挂面干燥项目,不同地方的气候对挂面干燥工艺有一定影响,因此经常需要我帮忙统计国内某城市一年的温湿度变化情况。以前用excle表格ctrl+C、ctrl+V方式得到一个城市的某年温湿度表,这种方式重复性操作多,而且查找数据麻烦。在学习了python后,决定做一个一劳永逸的绘制温湿度的脚本。

本文分以下几个方面介绍:

一、原始数据获取

原始数据从中国气象数据中心地面资料下载获取,数据说明可在网站上找到相关文档。加载需自己需要的数据后,几个小时后可以从订单中下载数据。数据格式是.txt的文件,文件里面有每个月的下载地址(每个月都有单独一个下载地址)。在linux操作系统中,使用wget工具批量下载数据:

wget -i S201806271736073722600.txt -P tem

获得2019年全国主要城市的温湿度数据文件,文件名中含有RHU是相对湿度数据,含有TEM的是温度数据。每个文件名都标有年份和月份日期,如201902。

2019年温湿度数据.png
湿度数据一共有11列,其中第一列是城市编码,官网下载文件查询编码对应城市,其余每列数据代表查询如图湿度数据每列对应表。
湿度数据.png 湿度数据每列对应表.png
同理,温度数据一共是13列,每列数据含义也可查询 温度数据.png
温度数据每列对应表.png

到此原始数据已经获取完毕。

二、应用pandas对原始数据筛选、整理

1.遍历原始数据文件
应用golb工具,遍历文件夹内所有文件名,并将文件名存入list中:

 for month in range(1, 13):
     if month < 10:
         list_tem = glob.glob(raw_data_path + '/*TEM*20190' + str(month) + '*')
         list_rhu = glob.glob(raw_data_path + '/*RHU*20190' + str(month) + '*')
     else:
         list_tem = glob.glob(raw_data_path + '/*TEM*2019' + str(month) + '*')
         list_rhu = glob.glob(raw_data_path + '/*RHU*2019' + str(month) + '*')

用pandas按月读取数据,并将每月数据按行拼接,注意拼接时需要忽略行索引,设置ignore_index=True。此时读入的数据是一列

 tem_data = pd.DataFrame()
     for raw_file in list_tem:
         tem_data_month = pd.read_table(raw_file, header=None, dtype=str)
         tem_data = pd.concat([tem_data, tem_data_month], axis=0, ignore_index=True)

设置列索引标题,分别为城市ID、日期、最小温度、最大温度、平均温度。遍历数据框分别处理每一行数据,用split()方法按空格将数据拆分存入列表,再将每列对应的数据分别处理后填入对应列中。

tem_data.columns = ['city_id']
     tem_data['date'] = None
     tem_data['min'] = None
     tem_data['max'] = None
     tem_data['avg'] = None
     list_x = []
     for i in tqdm(range(len(tem_data))):
         list_x = tem_data['city_id'][i].split()  # 分开第i行,x列的数据。split()默认是以空格等符号来分割,返回一个列表
         tem_data['city_id'][i] = list_x[0]  # 分割形成的列表,并将数据填入对应列
         # tem_data['data'][i] = time.strptime(' - '.join([list_x[4], list_x[5] , list_x[6]]), "%Y - %m - %d")
         tem_data['data'][i] = '-'.join([list_x[4], list_x[5], list_x[6]])
         tem_data['min'][i] = float(list_x[9]) / 10
         tem_data['avg'][i] = float(list_x[7]) / 10
         tem_data['max'][i] = float(list_x[8]) / 10

用同样方法处理湿度数据。

rhu_data = pd.DataFrame()
for raw_file in list_rhu:
    rhu_data_month = pd.read_table(raw_file, header=None, dtype=str)
    rhu_data = pd.concat([rhu_data, rhu_data_month], axis=0, ignore_index=True) rhu_data.columns = ['city_id']
rhu_data['data'] = None
rhu_data['rhu'] = None
list_x = []
 for i in tqdm(range(len(rhu_data))):
     list_x = rhu_data['city_id'][i].split() 
     rhu_data['city_id'][i] = list_x[0]  
     rhu_data['data'][i] = '-'.join([list_x[4], list_x[5], list_x[6]])
     rhu_data['rhu'][i] = list_x[7]

将温度和湿度数据融合。

df = pd.merge(tem_data, rhu_data, how='left', on=['city_id', 'data'])
all_data = pd.concat([all_data, df], axis=0, ignore_index=True)

保存处理后的数据

all_data.to_csv(os.path.join(root_path, 'all_data.csv')

三、用matplotlab工具绘制温湿度图像

读取城市每天的数据,并去除数据中的为观测值,(32766为为观测值,将为观测值用前一有效数值替代)

 # city_id = 54618
    if city_id in df['city_id']:
        day_data = df[df['city_id'] == city_id]
    else:
        print("没有该编号对应的城市")
    # # print(df.shape)

    x = df["data"]
    month_min = []
    month_max = []
    month_avg = []
    month_rhu = []
    # print(day_data)
    min_tem = day_data['min'].values.tolist()
    max_tem = day_data['max'].values.tolist()
    avg_tem = day_data['avg'].values.tolist()
    rhu = day_data['rhu'].values.tolist()
    modify_invalid_value(3276.6, avg_tem)
    modify_invalid_value(3276.6, min_tem)
    modify_invalid_value(3276.6, max_tem)
    modify_invalid_value(32766, rhu)

计算月平均值,并将月平均值保存在数据框中

days = 0
    for day in [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]:
        month_min.append(sum(min_tem[days:days + day]) / day)
        month_max.append(sum(max_tem[days:days + day]) / day)
        month_avg.append(sum(avg_tem[days:days + day]) / day)
        month_rhu.append(sum(rhu[days:days + day]) / day)
        days = days + day
  manth_data = pd.DataFrame(
        {"city_id": city_id, "min_tem": month_min, "max_tem": month_max, "avg_tem": month_avg, "avg_rhu": month_rhu})

绘制数据,并保存图像和结果

 months = [month for month in range(1, 13)]
    fig, ax1 = plt.subplots()
    ax1.plot(months, month_min, label=u"min_Tem")
    ax1.plot(months, month_max, label=u"max_Tem")
    ax1.plot(months, month_avg, label=u"avg_Tem")
    ax2 = ax1.twinx()
    ax2.plot(months, month_rhu, '--', label=u"avg_Rhu")
    # _xtick_labels_ = [' '.join(time.asctime(time.strptime(i, "%Y-%m-%d")).split()[2:3])for i in df["data"]]
    ax1.set_xlabel(u"Month")
    ax1.set_ylabel(u"TEM(℃)")
    ax2.set_ylabel("RHU(%)")

    min_tem_val = min(month_min)
    max_rhu_val = max(month_rhu)
    ax1.set_ylim(min_tem_val - 5, 50)
    ax2.set_ylim(-100, max_rhu_val + 10)
    _xtick_labels = ["{}".format(i) for i in range(1, 13)]
    plt.xticks(months, _xtick_labels)
    # plt.title("温湿度表")
    for a, b in zip(months, month_min):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_max):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_avg):
        ax1.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)
    for a, b in zip(months, month_rhu):
        ax2.text(a, b, "%.1f" % b, ha='center', va='bottom', fontsize=8)

    handles1, labels1 = ax1.get_legend_handles_labels()
    handles2, labels2 = ax2.get_legend_handles_labels()
    plt.legend(handles1 + handles2, labels1 + labels2, loc='lower center')
    plt.title('%d-TEM-RHU-Table' % city_id)
    plt.grid()
    plt.show()
    fig.savefig(os.path.join(root_path, 'image', str(city_id) + '_' + city_name + '.png'), bbox_inches='tight')

    # writer = pd.ExcelWriter(os.path.join(root_path,  'ShanDong.xlsx'))
    day_data.to_excel(writer, str(city_id) + city_name)
    manth_data.to_excel(writer, str(city_id) + city_name, startcol=9)

四、测试结果

用山东省六个城市的数据做测试。

city_id_dict = {54725: '惠民', 54776: '成山头', 54823: '济南', 54843: '潍坊', 54909: '定陶', 54916: '兖州'}
writer = pd.ExcelWriter(os.path.join(root_path, 'ShanDong.xlsx'))
for city_id, city_name in tqdm(city_id_dict.items()):
    main(city_id, city_name, writer)

writer.save()

输出结果:


54725_惠民.png
54776_成山头.png
54823_济南.png
54843_潍坊.png
54909_定陶.png
54916_兖州.png
各个城市温湿度数据输出到excle.png

五、总结

终于可以不用再复制粘贴的整理全国各地的温湿度数据了,而且将自己学的东西应用到日常工作中,提高工作效率是多么么么么么爽快的一件事啊。

仍未解决的问题:

1.生成的温湿度图,不能自动插入到相应excle对应的表格里。(不能再excle中追加插入图片)
2.没有解决生成图片中文出现编码错误。
3.数据处理不够简化,应该有很大的提升空间。

在代码过程中遇到的问题(找到相应解决方案):
数据读取与处理

1.如何遍历文件夹内文件?
2.怎样读取数据
3.怎样将不同文件的数据拼接
拼接时需要忽视行索引,
4.怎样将不同文件的数据融合
5.怎样设置dataframe的列标题
6.将读入的数据分为不同的列的方法
7.如何防止第一行数据当作列标题行
8.时间戳、时间元组、时间字符串的概念及相互转换
9.显示进度条的工具使用方法

图像绘制

1.如何设置横坐标
2.如何设置两个纵坐标
3.如何显示曲线中关键点数据值

上一篇下一篇

猜你喜欢

热点阅读