【问题标题】:Better ways to replace this function in pandas?在熊猫中替换此功能的更好方法?
【发布时间】:2020-04-26 10:30:35
【问题描述】:

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

例如,假设某小时/天,污染物中的最大值属于 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如何构成,函数如何实现。

【问题讨论】:

  • 为了优化,我可以给出的一个快速建议是,使用itertuples 而不是iterrows,这样更快。

标签: python pandas dataframe data-science


【解决方案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)

【讨论】:

  • 但这会为每个列值创建一个新的 df,其中包含 IQA,并将行的最大读数值作为“标签”。我错了吗?
  • 你是对的!我修复了它,所以它直接将它添加到您输入的 df 中。试一试,我很确定这就是您要寻找的答案。
猜你喜欢
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 2020-12-13
  • 2020-05-22
  • 2019-04-23
  • 2017-09-12
  • 2023-03-29
相关资源
最近更新 更多