替换熊猫中此功能的更好方法?

时间:2020-04-26 10:30:35

标签: python pandas dataframe data-science

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

AQI chart

例如,假设在某个小时/天中,污染物中的最大值属于PM10,其值为65ug / m3。参照图表确定空气质量指数为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以及如何实现该功能。

1 个答案:

答案 0 :(得分: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)