The Problem
I want to find the column name (row by row) in a dataframe where the max value occurs but if all values are zero, in the row, I want it to return an empty string or NaN. I can get the column where the max value occurs using idxmax but using this returns the first column name if all values are the same. I tried using idxmax in a df.apply lambda but I could never get it to work.
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
So the issues column is just a count (not sum) of non-zero values in the issue1, issue2 and issue3 columns.
Desired output:
issue1 issue2 issue3 issues top_issue
0 1 2 2 3 issue2
1 3 0 1 2 issue1
2 0 0 0 0 NaN
I want the top issue column like above where it gives me the column name with the highest value in it (first occurrence is fine) but when there are no issues (in row 3) I want a Null or empty value.
Things I Tried
1. Using idxmax
I was able to get the top_issue using this:
issue_cols = ['issue1','issue2','issue3']
df['top_issue'] = df[issue_cols].idxmax(axis=1)
But when all values in the issue columns are zero it gives me the first issue column.
Output:
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. Using idxmax with apply
I tried using apply - lambda but I kept getting errors with idxmax and was not able to figure it out.
df['top_issue'] = df.apply(lambda row: None if row['issues']==0 else row[issue_cols].idxmax(axis=1),axis=1)
Which gave me a ValueError
ValueError:
axismust be fewer than the number of dimensions (1)
Changed axis to zero which gave a TypeError
TypeError: reduction operation 'argmax' not allowed for this dtype
3. Using nlargest
df['top_issue'] = df.apply(lambda row: None if row['issues']==0 else row[issue_cols].nlargest(1).index.tolist(),axis=1)
This resulted in the following error
TypeError: Cannot use method 'nlargest' with dtype object
So then I had to double check that all my values were not of type object which they werent so I didn't know where to go from there.