在pandas中替换这个功能的更好方法?

问题描述 投票:1回答:1

我有一个数据框(df),由每天每小时的污染物读数(5)组成。最大的污染物值,不管是一小时还是一天的值,都将成为获取空气质量指数的参考,并将其作为标签添加到df中。

AQI chart

举个例子,假设某一天的某小时,污染物中最大值属于PM10,数值为65ugm3。当参考图表时,可以确定空气质量指数为4,因为它的读数在50-100之间。

到目前为止,我计算标签的方法是通过以下函数。

# IQA label function
def get_IQA_label(df):
  for index, val in df[[x for x in df.columns if x != 'date']].iterrows():
    max_column = np.argmax(val)
    max_column_val = np.max(val)

    if max_column == 0: # O_3
        if max_column_val <= 80:
           df.at[index, 'Label'] = 1

        if 80 < max_column_val <= 120:
           df.at[index, 'Label'] = 2

        if 120 < max_column_val <= 180:
           df.at[index, 'Label'] = 3

        if 180 < max_column_val <= 240:
           df.at[index, 'Label'] = 4

        if 240 < max_column_val <= 600:
           df.at[index, 'Label'] = 5

    if max_column == 1: # NO_2
        if max_column_val <= 40:
           df.at[index, 'Label'] = 1

        if 40 < max_column_val <= 100:
           df.at[index, 'Label'] = 2

        if 100 < max_column_val <= 200:
           df.at[index, 'Label'] = 3

        if 200 < max_column_val <= 400:
           df.at[index, 'Label'] = 4

        if 400 < max_column_val <= 1000:
           df.at[index, 'Label'] = 5

    if max_column == 2: # SO_2
        if max_column_val <= 100:
           df.at[index, 'Label'] = 1

        if 100 < max_column_val <= 200:
           df.at[index, 'Label'] = 2

        if 200 < max_column_val <= 350:
           df.at[index, 'Label'] = 3

        if 350 < max_column_val <= 500:
           df.at[index, 'Label'] = 4

        if 500 < max_column_val <= 1250:
           df.at[index, 'Label'] = 5

    if max_column == 3: # PM_10
        if max_column_val <= 20:
           df.at[index, 'Label'] = 1

        if 20 < max_column_val <= 35:
           df.at[index, 'Label'] = 2

        if 35 < max_column_val <= 50:
           df.at[index, 'Label'] = 3

        if 50 < max_column_val <= 100:
           df.at[index, 'Label'] = 4

        if 100 < max_column_val <= 1200:
           df.at[index, 'Label'] = 5

    if max_column == 4: # PM_2.5
        if max_column_val <= 10:
           df.at[index, 'Label'] = 1

        if 10 < max_column_val <= 20:
           df.at[index, 'Label'] = 2

        if 20 < max_column_val <= 25:
           df.at[index, 'Label'] = 3

        if 25 < max_column_val <= 50:
           df.at[index, 'Label'] = 4

        if 50 < max_column_val <= 800:
           df.at[index, 'Label'] = 5
  return df          

当通过df得到每日标签时,

day_df = get_IQA_label(day_df)
day_df

输出的结果是:

            O_3         NO_2        SO_2        PM10        PM25        CO          Label
date                            
2001-01-01  19.685217   53.789130   10.870435   20.306522   12.505127   1.055217    2.0
2001-01-02  25.496667   64.332083   10.119167   27.647917   12.505127   0.965417    2.0
2001-01-03  17.052917   69.595833   10.700833   33.777500   12.505127   0.965833    2.0
2001-01-04  18.335000   69.926666   11.472500   36.369583   12.505127   0.855000    2.0
2001-01-05  9.731667    65.272917   10.611250   32.444167   12.505127   1.174583    2.0
... ... ... ... ... ... ... ...
2018-04-27  52.875000   52.125000   1.000000    15.166667   7.125000    0.362500    1.0
2018-04-28  63.208333   30.625000   1.000000    13.000000   7.791667    0.245833    1.0
2018-04-29  68.375000   29.833333   1.000000    5.458333    3.750000    0.241667    1.0
2018-04-30  60.916667   37.375000   2.708333    4.083333    3.208333    0.279167    1.0
2018-05-01  52.000000   43.000000   4.000000    6.000000    4.000000    0.300000    1.0

我想知道还有什么其他方法可以获得标签, 我发现函数get_IQA_label(df)是一大块代码, 我觉得它可以优化得更好.

我想在把IQA图转换成df2,在计算主污染物df读数中每行的最大值时,创建某种函数,接受最大值和污染物名称作为参数,以便与df2进行比较,得到空气质量指数。

当计算max()值时,我使用。

# Getting max values from each contaminant on each row
max_value = df.max(axis=1)
max_value

而为了从最大值中获取列名,我使用了:

# Obtaining maximum value column name for each row
label_max_colName = hour_df.eq(hour_df.max(1), axis=0).dot(hour_df.columns)
label_max_colName

但是上面返回的是一个系列,我无法将这些系列传递给一个函数以获得所需的结果。

总之,不太清楚如何为AQI图表编写df2,以及如何实现函数。

python pandas dataframe data-science
1个回答
1
投票

其实我建议使用'剪切'功能。考虑到IQA图,这个应该可以用。

def get_IQA_label(df):

    df_2 = pd.DataFrame(index=df.index)

    df_2['O_3'] = pd.cut(input_df.O_3, bins=[0,80,120,180,240,600], 
                         labels=[1,2,3,4,5])
    df_2['NO_2'] = pd.cut(input_df.NO_2, bins=[0,40,100,200,400,1000], 
                          labels=[1,2,3,4,5])
    df_2['SO_2'] = pd.cut(input_df.SO_2, bins=[0,100,200,350,500,1250], 
                          labels=[1,2,3,4,5])
    df_2['PM10'] = pd.cut(input_df.PM10, bins=[0,20,35,50,100,1200], 
                          labels=[1,2,3,4,5])
    df_2['PM25'] = pd.cut(input_df.PM25, bins=[0,10,20,25,50,800], 
                          labels=[1,2,3,4,5])

    df['Label'] = temp_df.max(axis=1)
© www.soinside.com 2019 - 2024. All rights reserved.