由反应性气体仪生成的
臭氧、一氧化碳、二氧化硫、一氧化氮、二氧化氮、氮氧化物等数据为分钟级,从仪器上可以下载数据格式,导出的excel格式数据,一次支持最多64000行。所以我导出了几个月的数据用了4个excel表格。编写程序用统计小时平均,24小时平均值。同时处理其中的异常值,并把体积浓度转化为质量浓度。ppb、 ppm–>ug/m3。
首先excel另存为csv文件,虽然pandas也可以读取excel文件,便我我比较习惯处理csv文件.得到几个csv文件。
因为有要批处理多个文件,我用for root,dir,files in os.walk方法,可以循环读取文件,用建用好的空DataFrame来连接 返回值(pd.concat),得到全部的数据。
文件读取函数 read_Data.py
#Author: Wu dongqiao July 3, 2019
import numpy as np
import pandas as pd
import os
from datetime import datetime
def get_Data():
data = pd.DataFrame(columns=('时间', 'O3(ppb)', 'CO(ppm)', 'SO2(ppb)', 'NO(ppb)', 'NO2(ppb)', 'NOx(ppb)'))
for root, dirs, files in os.walk('D:\\data\\反应性气体'):
for tempFile in files:
path = os.path.join(root, tempFile)
tempdata = pd.read_csv(path,encoding='gbk')
data = pd.concat([data, tempdata])
# 将1列变成了时间类型
data['时间'] = pd.to_datetime(data['时间'])
data = data.set_index('时间')
# 处理异常值
data[(data['O3(ppb)'].str.contains('(报警)') == True)] = np.nan # 处理包含特定字符的字府串
data[(data['SO2(ppb)'].str.contains('(零校)') == True)] = np.nan
data[(data['SO2(ppb)'].str.contains('(满校)') == True)] = np.nan
data = data.replace('--', np.nan)
# 转为数值型
data[['O3(ppb)', 'CO(ppm)', 'SO2(ppb)', 'NO(ppb)', 'NO2(ppb)', 'NOx(ppb)']] = data[
['O3(ppb)', 'CO(ppm)', 'SO2(ppb)', 'NO(ppb)', 'NO2(ppb)', 'NOx(ppb)']].astype(float)
data.loc[data['O3(ppb)'] > 100] = np.nan
data.loc[data['NO2(ppb)'] < 0] = np.nan
# 册除nan
data = data.dropna()
return data
数据处理块
- 调用文件数据读取函数
- 体积浓度转质量浓度 (*摩尔质量/22.4) 运用apply(lambda )
- 重采样resample,平均到小时和天。对保存的小数位数处理,比如,CO保留4位小数,其它保留2位小数。
#Author: Wu dongqiao July 3, 2019
import read_Data as rd
import numpy as np
import pandas as pd
#获得数据
df=rd.get_Data()
#体积浓度转化为质量浓度
#对单列的值按进行修改
df['O3(ppb)']=df['O3(ppb)'].apply(lambda x:48*x/22.4)
#对单列值有条件的修改,部分值放大了1000倍,因为单位的原因需要处理
df.loc[df['CO(ppm)']<10,'CO(ppm)']=df.loc[df['CO(ppm)']<10]['CO(ppm)'].apply(lambda x :28*x/22.4)
df.loc[df['CO(ppm)']>10,'CO(ppm)']=df.loc[df['CO(ppm)']>10]['CO(ppm)'].apply(lambda x :28*x/(22.4*1000))
#对单列的值按进行修改
df['SO2(ppb)']=df['SO2(ppb)'].apply(lambda x:64*x/22.4,2)
df['NO(ppb)']=df['NO(ppb)'].apply(lambda x:30*x/22.4,2)
df['NO2(ppb)']=df['NO2(ppb)'].apply(lambda x:46*x/22.4,2)
#更改列名
df.rename(columns={'O3(ppb)':'O3(ug/m3)', 'CO(ppm)':'CO(mg/m3)', 'SO2(ppb)':'SO2(ug/m3)','NO(ppb)':'NO(ug/m3)','NO2(ppb)':'NO2(ug/m3)'}, inplace = True)
#删除多余的一列
df=df.drop(['NOx(ppb)'],axis=1)
df=df.dropna()
#定义保留2位或4位小数
format1=lambda x:"%.2f"%x
format2=lambda x:"%.4f"%x
#把分钟数据平均到小时
dfH=df.resample('H').mean()
#应用到保留小数位数
dfH['O3(ug/m3)']=dfH['O3(ug/m3)'].map(format1)
dfH['SO2(ug/m3)']=dfH['SO2(ug/m3)'].map(format1)
dfH['NO(ug/m3)']=dfH['NO(ug/m3)'].map(format1)
dfH['NO2(ug/m3)']=dfH['NO2(ug/m3)'].map(format1)
dfH['CO(mg/m3)']=dfH['CO(mg/m3)'].map(format2)
#保存为.csv
dfH.to_csv('M:\\反应性气体小时平均浓度.csv')
#统计到日平均
dfD=df.resample('D').mean()
dfD['O3(ug/m3)']=dfD['O3(ug/m3)'].map(format1)
dfD['SO2(ug/m3)']=dfD['SO2(ug/m3)'].map(format1)
dfD['NO(ug/m3)']=dfD['NO(ug/m3)'].map(format1)
dfD['NO2(ug/m3)']=dfD['NO2(ug/m3)'].map(format1)
dfD['CO(mg/m3)']=dfD['CO(mg/m3)'].map(format2)
dfD.to_csv('M:\\反应性气体24小时平均浓度.csv')
得到了想要的数据
==问题 ==???我发现我用resample重采样生成的dataframe中自动补全了所有规则日期,即使有部分时间段是缺失的,而且我用dfH=dfH.dropna()这样的方法删不掉nan行段,而且不报错。有点奇怪,我正在查找问题,不过我先用另外的方法来解决,
我重写了数据处理的方法,不用resample。看起来复杂了些。
pd.data_range生成时间段,H以小时,D按天。在时间段里循环读取并连接。
#Author: Wu dongqiao July 11, 2019
import read_Data as rd
import pandas as pd
import numpy as np
#获取数数据
data=rd.get_Data()
# #创建时间序列
temptime = pd.Series(pd.date_range('3/1/2019', '6/30/2019', freq='H'))
#定义空列表,用以保存数据
yyyymmdd = []
O3 = []
CO = []
SO2 = []
NO = []
NO2 = []
#以天为单位统计数据
for i in temptime:
tempmeandata = data[str(i.strftime('%Y-%m-%d %H'))].mean()
yyyymmdd.append(str(i.strftime('%Y-%m-%d %H')))
O3.append(round(tempmeandata[0]*48/22.4, 2))
#其中CO有ppm和ppb两种差1000倍,分别处理
#体积浓度*分子量除以22.4,转化为质量浓度
if tempmeandata[1] > 10:
CO.append(round(tempmeandata[1] * 28 / (1000 * 22.4), 4))
else:
CO.append(round(tempmeandata[1] * 28 / 22.4, 4))
SO2.append(round(tempmeandata[2]*64/22.4, 2))
NO.append(round(tempmeandata[3]*30/22.4, 2))
NO2.append(round(tempmeandata[4]*46/22.4, 2))
#创建DataFrame数据
Ddata = pd.DataFrame({'时间': yyyymmdd, 'O3(ug/m3)': O3, 'CO(mg/m3)': CO, 'SO2(ug/m3)': SO2, 'NO(ug/m3)': NO, 'NO2(ug/m3)': NO2 })
#处理异常数据
Ddata=Ddata.dropna()
print(Ddata.describe())
#输出数据表
# Ddata.to_csv('M:\\反应性气体小时平均质量浓度.csv')
此格式生成的data可以用.dropna删除缺失值, 运行print(Ddata.describe())后得到统计结果