Python模糊评价空气质量(数据源为Excel表)

  1. 建立评判因子集

        根据《环境空气质量标准》(GB 3095—2012),主要空气污染物包括以下 6 项:二氧化氮(NO2)、一 氧化碳(CO)、二氧化硫(SO2)、臭氧(O3)、粒径小于或等于10 μm的颗粒物(PM10)、粒径小于或等于2.5μm的颗粒物(PM2.5)。因此,建立影响空气质量污染物所 对 应 的 因 子 集 :U ={u1,u2,u3,u4,u5,u6 }={SO2,NO2, CO,O3,PM10,PM2.5}。

  1. 建立评价集

        结合《环境空气质量标准》(GB3095—2012)和上海市环境监测中心站检测污染物浓度的实际情况,建立四级评价集:

式中,i 表示空气质量评价因子,i=1,2,...,6;j 表示空气质量评价等级,j=1,2,...,4。

空气质量评价标准4个等级,Ⅰ(优)、Ⅱ(良)、Ⅲ(轻度污染)、Ⅳ(中度污染),具体见下表:

表格 1评价指标及浓度限差

Python模糊评价空气质量(数据源为Excel表)_第1张图片

  1. 建立隶属函数

采用降半阶梯形隶属度函数,建立评价因子对空气质量评价等级标准的隶属函数,从而建立模糊关系矩阵隶属度的计算公式如下:

当j=1时,

Python模糊评价空气质量(数据源为Excel表)_第2张图片

当j=2,3时,

Python模糊评价空气质量(数据源为Excel表)_第3张图片

当j=4时,

Python模糊评价空气质量(数据源为Excel表)_第4张图片

式(1)~(3)中,

xi为第i个评价因子的实测值;Sij为第i个评价因子的第j污染等级的浓度限值;rij为 第i个评价因子对第j污染等级的隶属度。将上海市某一天中的24小时数据进行均值化后代入到对应的隶属函数中,通过计算可得模糊关系矩阵R=[rij].

  1. 确定权重因子集合

        空气质量评价中污染因子的权重是衡量各污染物对空气质量影响的重要程度,权重值越大,对空气质量影响越大,否则就越小。

        模糊综合评判的赋权方法包括标准赋权法和主因素突出赋权法。每个评价因子对空气质量的影响都存在差异,对空气质量评价结果的影响也各不相同,所以要考虑每个评价因子在空气质量评价中所占的权重,采用超标加权法来计算每个评价因子的权重,通过归一化方法处理,得到权重集A={a1,a2,a3,a4,a5,a6}

其中权重系数的计算公式如下:

Python模糊评价空气质量(数据源为Excel表)_第5张图片

        在该权重系数公式中,ai表示评价因子的权重,m表示评价因子的个数,Si表示空气质量等级及其对应评价因子的浓度限值的平均值,Ci表示标准的实测值。

        将对应的数据代入到权重系数公式中,将可以得到权重集。

  1. 模糊综合评判

        根据模糊矩阵和权重集的计算结果,可将A和R进行模糊矩阵的复合运算,可得:

根据最大隶属度原则,取

作为空气质量模糊综合评价的结果。

  1. 后端实现代码

        将上述模糊评价运行的步骤在后端利用Flask框架使用Python代码实现,并且将最终结果以json的格式返回,使得前端可以接收数据并且显示分析处理结果。

Excel表数据格式如下:

Python模糊评价空气质量(数据源为Excel表)_第6张图片

from flask import Flask,request,jsonify,Response
from flask.views import MethodView
import arcpy
import psycopg2
from flask_cors import CORS#跨域请求伪造
import geopandas as gpd
import json
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

@app.route('/mohupj')
def mohupj():
    # 读取数据集
    readfile = pd.read_excel(r"D:\junior_year_2\Webgis开发小组\data\上海站点\上海站点\shanghai0202.xlsx")
    lists = [1, 2, 3, 4, 5, 6, 7, 8, 9]  ##获取各个站点的行数据
    jiancedianname = []
    for n1 in lists:
        jiance_ = readfile.iloc[n1 - 1, 1]  ##获取城市名称
        jiancedianname.append(jiance_)
    print(jiancedianname)  ##监测点名称
    print("监测点数量:")
    print(len(jiancedianname))
    # 环境空气质量等级及对应的污染物项目浓度限值
    dataparameters = [[15, 35, 75, 120],
                      [40, 70, 140, 210],
                      [20, 60, 100, 140],
                      [20, 40, 60, 80],
                      [100, 160, 220, 280],
                      [2, 4, 6, 8]]
    parameters = pd.DataFrame(dataparameters, index=["PM2.5", "PM10", "SO2", "NO2", "O3", "CO"], columns=[0, 1, 2, 3])
    # print(parameters.iloc[1,0])    #parameters.iloc[i,j]获得第i行第j列的数据
    '''#建立隶属度函数  采用降半阶梯形隶属度函数'''
    def lishudu(pollution):
        V = pd.DataFrame({}, index=["PM2.5", "PM10", "SO2", "NO2", "O3", "CO"], columns=[0, 1, 2, 3])
        colu = 0
        while colu <= 3:
            if colu == 0:
                # 对于第1污染等级
                row = 0
                while row <= 5:
                    if (pollution.iloc[row, 0] <= parameters.iloc[row, colu]):
                        V.iloc[row, colu] = 1
                    if (pollution.iloc[row, 0] < parameters.iloc[row, colu + 1] and pollution.iloc[row, 0] >
                            parameters.iloc[row, colu]):
                        V.iloc[row, colu] = ((parameters.iloc[row, colu + 1]) - (pollution.iloc[row, 0])) / (
                                    (parameters.iloc[row, colu + 1]) - (parameters.iloc[row, colu]))
                    if (pollution.iloc[row, 0] >= parameters.iloc[row, colu + 1]):
                        V.iloc[row, colu] = 0
                    row = row + 1
            if colu == 1 or colu == 2:  # 对于2 3等级
                row = 0
                while row <= 5:
                    if (pollution.iloc[row, 0] >= parameters.iloc[row, colu + 1] or pollution.iloc[row, 0] <
                            parameters.iloc[row, colu - 1]):
                        V.iloc[row, colu] = 0
                    if (parameters.iloc[row, colu] < pollution.iloc[row, 0] and pollution.iloc[row, 0] <
                            parameters.iloc[row, colu + 1]):
                        V.iloc[row, colu] = ((parameters.iloc[row, colu + 1]) - (pollution.iloc[row, 0])) / (
                                    (parameters.iloc[row, colu + 1]) - (parameters.iloc[row, colu]))
                    if (parameters.iloc[row, colu - 1] <= pollution.iloc[row, 0] and pollution.iloc[row, 0] <=
                            parameters.iloc[row, colu]):
                        V.iloc[row, colu] = ((pollution.iloc[row, 0] - parameters.iloc[row, colu - 1])) / (
                        (parameters.iloc[row, colu] - parameters.iloc[row, colu - 1]))
                    row = row + 1
            if colu == 3:  # 对于4等级
                row = 0
                while row <= 5:
                    if (pollution.iloc[row, 0] >= parameters.iloc[row, colu]):
                        V.iloc[row, colu] = 1
                    if (pollution.iloc[row, 0] <= parameters.iloc[row, colu - 1]):
                        V.iloc[row, colu] = 0
                    if (parameters.iloc[row, colu - 1] < pollution.iloc[row, 0] and pollution.iloc[row, 0] <
                            parameters.iloc[row, colu]):
                        V.iloc[row, colu] = ((pollution.iloc[row, 0]) - (parameters.iloc[row, colu - 1])) / (
                                    (parameters.iloc[row, colu]) - (parameters.iloc[row, colu - 1]))
                    row = row + 1
            colu = colu + 1
        return V
    lishududangeresult = []  ##输入每个监测点的隶属度
    jiancepollution = []  # 监测点中各个污染物的数据
    for n1 in lists:
        a = (readfile.iloc[(n1 - 1):n1, [6, 7, 8, 9, 10, 11]])
        # #读取每个因素的值
        datapollution = [int(a.iloc[0, 0]),
                         int(a.iloc[0, 1]),
                         int(a.iloc[0, 2]),
                         int(a.iloc[0, 3]),
                         int(a.iloc[0, 4]),
                         int(a.iloc[0, 5])]
        pollution = pd.DataFrame(datapollution, index=["PM2.5", "PM10", "SO2", "NO2", "O3", "CO"], columns=[0])
        jiancepollution.append(pollution)  ###获得整体所有的污染物数据
        result = lishudu(pollution)
        lishududangeresult.append(result)
    print("各个监测点隶属度结果:")
    print(lishududangeresult)
    print("第二个监测点隶属度结果:")
    print(lishududangeresult[1])
    pingjiaave = []  ##存储所有评价因子的平均值
    '''求每个评价因子浓度限差平均值'''
    for pjitem in dataparameters:  ##pjitemave为每个类型评价因子对应的各个等级的限差
        pjitemave = sum(pjitem) / len(pjitem)
        pingjiaave.append(pjitemave)  ##将各个评价因子的平均值存入列表
    quanzhongall = []  ##存储所有监测点污染物权重值
    print("所有评价因子的平均值")
    print(pingjiaave)
    for item in jiancepollution:
        '''求权重系数分母'''
        for n in range(len(pingjiaave)):
            quanzhongFMsum = []  ##做为中间量存储单个监测点污染物权重值
            m = len(item)  ####评价因子的个数为  6
            for p in range(m):
                quanzhongFZ = item[0][p] / pingjiaave[n]
                quanzhongFMsum.append(quanzhongFZ)  ####将全部的分子结果存入列表中
                p = p + 1
            FM = sum(quanzhongFMsum)  ##得到权重计算的分母
            quanzhongtemp = []  ##得到单个监测点的权重
            for i in range(m):
                result1 = (item[0][i] / pingjiaave[n]) / FM
                quanzhongtemp.append(result1)  ###将单个监测点权重存入列表
            quanzhongall.append(quanzhongtemp)
            break  ###跳出当前循环
        continue  ###跳出当前循环
        n = n + 1
    print("全部权重集:")
    print(quanzhongall)  #####获得9个监测点的污染物权重集
    print("全部权重集长度:")
    print(len(quanzhongall))
    print("第二个测站点权重集:")
    print(quanzhongall[1])
    mohupjresultall_value = []  ##存储所有监测点模糊评价结果  数值
    mohupjresultall_index = []  ##存储所有监测点模糊评价结果  等级
    '''对每个监测点进行模糊评价'''
    for num in range(len(jiancedianname)):
        mohupjresult = []  ##存储单个监测点的评价结果
        quanzhongdg = quanzhongall[num]  ##单个监测点权重集
        lishududg = lishududangeresult[num]  ##单个监测点隶属度集
        mohupjresult = np.dot(quanzhongdg, lishududg)  # 矩阵乘法  得到复合运算结果
        print("单个监测点模糊评价初步结果")
        print(mohupjresult)
        '''根据最大隶属度原则找到对应的等级以及其数值'''
        max_value = max(mohupjresult)
        max_index = np.where(mohupjresult == max_value)
        mohupjresultall_index.append(max_index[0][0])
        # mohupjresultfinal.append(max_index)
        mohupjresultall_value.append(max_value)
        num = num + 1
    print("各个站点最终模糊评价结果:")
    print("对应等级:")
    print(mohupjresultall_index)
    print("结果数值")
    print(mohupjresultall_value)
    ##创建包含int64类型的数据数组
    mohupjresultall_index_=np.array(mohupjresultall_index,dtype=np.int64)
    #int64类型的数据转换为int类型
    mohupjresultall_index_2=mohupjresultall_index_.astype(int).tolist()
    data = []
    for value, level, name in zip(mohupjresultall_value,mohupjresultall_index_2, jiancedianname):
        entry = {
            "value": value,
            "level": level,
            "name": name
        }
        data.append(entry)
    json_result = json.dumps(data, indent=4)
    return json_result

接口返回数据:

[ { "value": 0.31607407407407406, "level": 1, "name": "\u666e\u9640" }, { "value": 0.36604361370716504, "level": 0, "name": "\u5341\u4e94\u5382" }, { "value": 0.34426605504587154, "level": 3, "name": "\u8679\u53e3" }, { "value": 0.3040723981900453, "level": 0, "name": "\u5f90\u6c47\u4e0a\u5e08\u5927" }, { "value": 0.3009803921568627, "level": 1, "name": "\u9752\u6d66\u6dc0\u5c71\u6e56" }, { "value": 0.350210970464135, "level": 3, "name": "\u9759\u5b89\u76d1\u6d4b\u7ad9" }, { "value": 0.3404878048780488, "level": 0, "name": "\u6d66\u4e1c\u5ddd\u6c99" }, { "value": 0.31309523809523804, "level": 0, "name": "\u6d66\u4e1c\u65b0\u533a\u76d1\u6d4b\u7ad9" }, { "value": 0.3365231259968102, "level": 0, "name": "\u6d66\u4e1c\u5f20\u6c5f" } ]

手动实现算法,如有不足之处望各位大佬在评论区留言告知,感谢!!

你可能感兴趣的:(python,excel)