开发者问题收集

查找最大值的列,但如果所有值都为零,则不返回任何值

2021-08-12
1300

问题

我想在数据框中逐行查找出现最大值的列名,但如果该行中的所有值都为零,我希望它返回一个空字符串或 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

因此,问题列只是 issue1、issue2 和 issue3 列中非零值的 计数 (而不是总和)。

所需输出:

  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 must be fewer than the number of dimensions (1)

将轴更改为零,这给了我一个 TypeError

TypeError: reduction operation 'argmax' not allowed for this dtype

3.使用 nlargest

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

这导致了以下错误

TypeError: Cannot use method 'nlargest' with dtype object

所以我不得不仔细检查我的所有值都不是对象类型,所以我不知道接下来该怎么做。

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
Yogesh Bhandari
2021-08-12

axis=1 上对与模式 issue\d+ 匹配的列使用 DataFrame.apply ,然后如果最大值为零则取 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
ThePyGuy
2021-08-12