pandas对反应性气体批处理,体积浓度转质量浓度apply、lambda,小时、天统计resample

由反应性气体仪生成的
数据
臭氧、一氧化碳、二氧化硫、一氧化氮、二氧化氮、氮氧化物等数据为分钟级,从仪器上可以下载数据格式,导出的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

数据处理块

  1. 调用文件数据读取函数
  2. 体积浓度转质量浓度 (*摩尔质量/22.4) 运用apply(lambda )
  3. 重采样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())后得到统计结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值