使用python进行排放清单不确定性分析(蒙特卡洛模拟)

        目前能够进行蒙特卡洛模拟的软件有很多,如crystal ball、AUVtoolpro等,在排放清单数据较为简单,源类较少的情况下使用以上软件来操做是极为方便的,但是当排放b清单原分类较为繁杂,数据的前期处理就变得异常繁琐,充斥着大量的重复工作。使用python或者其他语言来进行编程分析可以降低前期数据处理的难度,减少无意义的重复劳动。

如果各位有不明白的地方可以添加好友询问,vx:wonderful11451

一、引入库包

        笔者使用的库包为数据处理中较为常用的pandas以及numpy,pandas主要用来进行数据的读取、写入以及统计等工作,numpy则主要进行蒙特卡洛模拟中的随机抽样工作。

import pandas as pd
import numpy as np

 二、读取清单文件

        清单文件的格式需要包括活动水平、sigma1(活动水平概率分布第二参数)、sigma2(排放因子活动水平第二参数)、排放源类、污染物排放因子以及污染物去除效率,以工业锅炉排放源为例,具体格式见下图:

 

 

file = r"清单数据.xlsx"

 三、定义模拟函数

        函数设置如下:

def uncert_excel(file, spc):
    xlsx = r"2021_"+spc+".xlsx"
    xlsx2 = pd.ExcelWriter(xlsx)
    ll2 = pd.DataFrame()
    for i in range(41):     
##41为excel表格中的sheet数量,根据个人需要自行输入。

##获取sheet名称
        df = pd.read_excel(file, sheet_name=i)
        df2 = pd.read_excel(file, sheet_name=None)
        df = df[df['活动水平'] != 0]
        df = df.reset_index()
        print(i)
        name_yuanlei = list(df2.keys())[i]
        print(name_yuanlei)
  
        ll = pd.DataFrame()

##根据条件筛选需要的数据
        if spc + '排放因子' in df.columns:
            dfSO2 = df[df[spc + '排放因子'] != 0]
            dfSO2 = dfSO2.reset_index()
##删除排放因子为0的行


            if spc + '去除效率' in dfSO2.columns:
                a = dfSO2['活动水平'] * (1 - dfSO2[spc + '去除效率'] / 100)
                dfSO2.insert(0, spc, a)
##计算活动水平*(1-去除效率),此处笔者的文件去除效率为小于100的数值,所以需要除100,此处根据个人需要调整。


            else:
                a = dfSO2['活动水平']
                dfSO2.insert(0, spc, a)
##有些源类不存在去除效率,如果没有去除效率这一栏,则跳过上述计算步骤


            for j in range(len(dfSO2[spc])):
                number = dfSO2[spc][j]
                ef = dfSO2[spc + '排放因子'][j]
                sigma_q = dfSO2['sigma1'][j]
                sigma_ef = dfSO2['sigma2'][j]
                number2 = np.log(number)
                ef2 = np.log(ef)
                a = np.random.lognormal(mean=number2, sigma=sigma_q, size=10000)
                b = np.random.lognormal(mean=ef2, sigma=sigma_ef, size=10000)
##根据输入的活动水平、排放因子与对应的sigma1、sigma2进行10000次抽样

                c = a * b
##计算最终排放量


                s_type = dfSO2['第一级排放源'][j] + dfSO2['第二级排放源'][j] + dfSO2['第三级排放源'][j] + dfSO2['第四级排放源'][j] + dfSO2['产品/技术子类型'][j]
                ll[str(j)] = pd.DataFrame(c)
                # name = dfSO2['一级排放源'][j]+dfSO2['二级排放源'][j]+dfSO2['三级排放源'][j]+dfSO2['四级排放源'][j]+dfSO2['产品/技术子类型'][j]
                ll2[name_yuanlei] = ll.apply(lambda x: x.sum(), axis=1)
    ll2[spc + '_all'] = ll2.apply(lambda x: x.sum(), axis=1)
    a = ll2[spc+"_all"]
    b = a.quantile([0.025,0.975])
##计算结果的95%置信度下的数据,并把保存至excel文件


    b.to_excel(xlsx2, sheet_name='分位数据')
    ll2.to_excel(xlsx2, sheet_name='ALL_sum',index=None)
    xlsx2.save()
    xlsx2.close()

四、全部代码及输出结果​​​​​​​

import pandas as pd
import numpy as np

file = r"清单数据.xlsx"

def uncert_excel(file, spc):
    xlsx = r"2021_"+spc+".xlsx"
    xlsx2 = pd.ExcelWriter(xlsx)
    ll2 = pd.DataFrame()
    for i in range(41):     
##41为excel表格中的sheet数量,根据个人需要自行输入。

##获取sheet名称
        df = pd.read_excel(file, sheet_name=i)
        df2 = pd.read_excel(file, sheet_name=None)
        df = df[df['活动水平'] != 0]
        df = df.reset_index()
        print(i)
        name_yuanlei = list(df2.keys())[i]
        print(name_yuanlei)
  
        ll = pd.DataFrame()

##根据条件筛选需要的数据
        if spc + '排放因子' in df.columns:
            dfSO2 = df[df[spc + '排放因子'] != 0]
            dfSO2 = dfSO2.reset_index()
##删除排放因子为0的行


            if spc + '去除效率' in dfSO2.columns:
                a = dfSO2['活动水平'] * (1 - dfSO2[spc + '去除效率'] / 100)
                dfSO2.insert(0, spc, a)
##计算活动水平*(1-去除效率),此处笔者的文件去除效率为小于100的数值,所以需要除100,此处根据个人需要调整。


            else:
                a = dfSO2['活动水平']
                dfSO2.insert(0, spc, a)
##有些源类不存在去除效率,如果没有去除效率这一栏,则跳过上述计算步骤


            for j in range(len(dfSO2[spc])):
                number = dfSO2[spc][j]
                ef = dfSO2[spc + '排放因子'][j]
                sigma_q = dfSO2['sigma1'][j]
                sigma_ef = dfSO2['sigma2'][j]
                number2 = np.log(number)
                ef2 = np.log(ef)
                a = np.random.lognormal(mean=number2, sigma=sigma_q, size=10000)
                b = np.random.lognormal(mean=ef2, sigma=sigma_ef, size=10000)
##根据输入的活动水平、排放因子与对应的sigma1、sigma2进行10000次抽样

                c = a * b
##计算最终排放量


                s_type = dfSO2['第一级排放源'][j] + dfSO2['第二级排放源'][j] + dfSO2['第三级排放源'][j] + dfSO2['第四级排放源'][j] + dfSO2['产品/技术子类型'][j]
                ll[str(j)] = pd.DataFrame(c)
                # name = dfSO2['一级排放源'][j]+dfSO2['二级排放源'][j]+dfSO2['三级排放源'][j]+dfSO2['四级排放源'][j]+dfSO2['产品/技术子类型'][j]
                ll2[name_yuanlei] = ll.apply(lambda x: x.sum(), axis=1)
    ll2[spc + '_all'] = ll2.apply(lambda x: x.sum(), axis=1)
    a = ll2[spc+"_all"]
    b = a.quantile([0.025,0.975])
##计算结果的95%置信度下的数据,并把保存至excel文件


    b.to_excel(xlsx2, sheet_name='分位数据')
    ll2.to_excel(xlsx2, sheet_name='ALL_sum',index=None)
    xlsx2.save()
    xlsx2.close()

Al = ['SO2','NOx','CO','VOC','NH3','PM2.5','PMcorase','BC','OC']
for spc in Al:
    uncert_excel(file,spc)

           表格中包括抽样数据以及用于计算不确定性的排放量数据。

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值