【问题标题】:Find the minimum value in a Pandas dataframe and add a label on new column在 Pandas 数据框中找到最小值并在新列上添加标签
【发布时间】:2021-03-28 13:04:03
【问题描述】:

我可以对我的 python pandas 代码进行哪些改进以使其更高效?就我而言,我有这个数据框

In [1]: df = pd.DataFrame({'PersonID': [1, 1, 1, 2, 2, 2, 3, 3, 3],
                           'Name': ["Jan", "Jan", "Jan", "Don", "Don", "Don", "Joe", "Joe", "Joe"],
                           'Label': ["REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL"],
                           'RuleID': [55, 55, 55, 3, 3, 3, 10, 10, 10],
                           'RuleNumber': [3, 4, 5, 1, 2, 3, 234, 567, 999]})

这给出了这个结果:

In [2]: df
Out[2]: 
   PersonID Name Label  RuleID  RuleNumber
0         1  Jan   REL      55          3
1         1  Jan   REL      55          4
2         1  Jan   REL      55          5
3         2  Don   REL       3          1
4         2  Don   REL       3          2
5         2  Don   REL       3          3
6         3  Joe   REL      10        234
7         3  Joe   REL      10        567
8         3  Joe   REL      10        999

我需要在这里完成的是将标签列下的字段更新为 MAIN,以获取与应用于人员 ID 和姓名的每个规则 ID 关联的最低规则值。因此,结果需要如下所示:

In [3]: df
Out[3]:
   PersonID Name Label  RuleID  RuleNumber
0         1  Jan  MAIN      55           3
1         1  Jan   REL      55           4
2         1  Jan   REL      55           5
3         2  Don  MAIN       3           1
4         2  Don   REL       3           2
5         2  Don   REL       3           3
6         3  Joe  MAIN      10         234
7         3  Joe   REL      10         567
8         3  Joe   REL      10         999

这是我为此编写的代码:

In [4]:

df['Label'] = np.where(
        df['RuleNumber'] ==
        df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].transform('min'),
        "MAIN", df.Label)

有没有更好的方法来更新标签列下的值?我觉得我是在强行通过,这可能不是最有效的方法。

我使用以下 SO 线程得出我的结果:

Replace column values within a groupby and condition

Replace values within a groupby based on multiple conditions

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.idxmin.html

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.transform.html

Using Pandas to Find Minimum Values of Grouped Rows

任何建议将不胜感激。

谢谢。

【问题讨论】:

    标签: python pandas numpy group-by min


    【解决方案1】:

    您似乎可以按分组的idxmin 进行过滤,而不管排序顺序如何,并据此更新RuleNumber。您可以使用locnp.wheremaskwhere,如下所示:

    df.loc[df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].idxmin(), 'Label'] = 'MAIN'
    

    您尝试使用np.where 或:

    df['Label'] = (np.where((df.index == df.groupby(['PersonID', 'Name', 'RuleID'])
                             ['RuleNumber'].transform('idxmin')), 'MAIN', 'REL'))
    df
    Out[1]: 
       PersonID Name Label  RuleID  RuleNumber
    0         1  Jan  MAIN      55           3
    1         1  Jan   REL      55           4
    2         1  Jan   REL      55           5
    3         2  Don  MAIN       3           1
    4         2  Don   REL       3           2
    5         2  Don   REL       3           3
    6         3  Joe  MAIN      10         234
    7         3  Joe   REL      10         567
    8         3  Joe   REL      10         999
    

    使用mask 或它的逆where 也可以:

    df['Label'] = (df['Label'].mask((df.index == df.groupby(['PersonID', 'Name', 'RuleID'])
                             ['RuleNumber'].transform('idxmin')), 'MAIN'))
    

    df['Label'] = (df['Label'].where((df.index != df.groupby(['PersonID', 'Name', 'RuleID'])
                             ['RuleNumber'].transform('idxmin')), 'MAIN'))
    

    【讨论】:

      【解决方案2】:
      import pandas as pd
      
      df = pd.DataFrame({'PersonID': [1, 1, 1, 2, 2, 2, 3, 3, 3],
      'Name': ["Jan", "Jan", "Jan", "Don", "Don", "Don", "Joe", "Joe", "Joe"],
      'Label': ["REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL"],
      'RuleID': [55, 55, 55, 3, 3, 3, 10, 10, 10],
      'RuleNumber': [3, 4, 5, 1, 2, 3, 234, 567, 999]})
      
      df.loc[df.groupby('Name')['RuleNumber'].idxmin()[:], 'Label'] = 'MAIN'
      

      【讨论】:

      • 最好将索引值直接传递给.loc。它有效,但无需搜索.isin 是否存在索引值。您基本上可以使用df.loc[indexes, 'Label'] = 'MAIN' 来删除使用isin 进行搜索的冗余步骤。
      【解决方案3】:

      在 PersonID 上使用 duplicated

      df.loc[~df['PersonID'].duplicated(),'Label'] = 'MAIN'
      print(df)
      

      输出:

         PersonID Name Label  RuleID  RuleNumber
      0         1  Jan  MAIN      55           3
      1         1  Jan   REL      55           4
      2         1  Jan   REL      55           5
      3         2  Don  MAIN       3           1
      4         2  Don   REL       3           2
      5         2  Don   REL       3           3
      6         3  Joe  MAIN      10         234
      7         3  Joe   REL      10         567
      8         3  Joe   REL      10         999
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多