【问题标题】:Find column where the max values but return nothing if all values are zero occurs如果所有值都为零,则查找最大值但不返回任何内容的列
【发布时间】:2021-08-12 12:33:36
【问题描述】:

问题

我想在出现最大值的数据框中找到列名(逐行),但如果所有值都为零,则在该行中,我希望它返回一个空字符串或 NaN。 我可以使用 idxmax 获取出现最大值的列,但是如果所有值都相同,则使用它会返回第一个列名。我尝试在 df.apply lambda 中使用 idxmax,但我无法让它工作。

df = pd.DataFrame({'cat1':[1,3,0], 'cat2':[2,0,0], 'cat3':[2,1,0], 'issues':[3,2,0]})

  issue1  issue2  issue3    issues
0   1       2        2        3
1   3       0        1        2
2   0       0        0        0

所以问题列只是问题1、问题2和问题3列中非零值的计数(不是总和)。

期望的输出:

  issue1  issue2  issue3    issues  top_issue
0   1       2        2        3      issue2
1   3       0        1        2      issue1
2   0       0        0        0       NaN

我想要像上面一样的最重要的问题列,它为我提供了其中具有最高值的列名(第一次出现很好)但是当没有问题时(在第 3 行)我想要一个 Null 或空值。

我尝试过的事情

1。使用 idxmax

我能够使用这个获得 top_issue:

issue_cols = ['issue1','issue2','issue3']
df['top_issue'] = df[issue_cols].idxmax(axis=1)

但是当问题列中的所有值都为零时,它会给我第一个问题列。

输出:

  issue1  issue2  issue3    issues  top_issue
0   1       2        2        3      issue2
1   3       0        1        2      issue1
2   0       0        0        0      issue1

2。将 idxmax 与 apply 一起使用

我尝试使用 apply - lambda,但 idxmax 不断出现错误,无法弄清楚。

df['top_issue'] = df.apply(lambda row: None if row['issues']==0 else row[issue_cols].idxmax(axis=1),axis=1)

这给了我一个 ValueError

ValueError: axis 必须小于维数 (1)

将轴更改为零,导致 TypeError

TypeError: 此 dtype 不允许归约操作 'argmax'

3。使用最大

df['top_issue'] = df.apply(lambda row: None if row['issues']==0 else row[issue_cols].nlargest(1).index.tolist(),axis=1)

这导致了以下错误

TypeError: 不能对 dtype 对象使用方法 'nlargest'

所以我必须仔细检查我的所有值都不是对象类型,它们不是,所以我不知道从那里去哪里。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    在与模式issue\d+ 匹配的列上使用DataFrame.apply,在axis=1 上使用nan,如果最大值为零,则使用该轴上的最大索引。

    result=(df.assign(top_issue=df[df.columns[df.columns.str.match('issue\d+')]]
            .apply(lambda x: float('nan') if x.max()==0
            else x.idxmax(), axis=1)
                       )
             )
    

    输出:

       issue1  issue2  issue3  issues top_issue
    0       1       2       2       3    issue2
    1       3       0       1       2    issue1
    2       0       0       0       0       NaN
    

    【讨论】:

      【解决方案2】:

      您可以先将0 替换为NaN,然后应用idxmax 以获得所需的输出。

      issue_cols = ['issue1','issue2','issue3']
      df['top_issue'] = df[issue_cols].replace(0, np.nan).idxmax(axis=1)
      

      输出:

           issue1  issue2  issue3  issues top_issue
      0       1       2       2       3    issue2
      1       3       0       1       2    issue1
      2       0       0       0       0       NaN
      

      【讨论】:

      • 简单漂亮;)
      猜你喜欢
      • 2012-10-12
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      • 2018-07-29
      • 2019-08-14
      • 1970-01-01
      相关资源
      最近更新 更多