'Pandas create column that shows absolute max value of the row, but keeps negatives

I have a df that looks like this:

         a      b      c
124    -3.09  -0.38   2.34
2359    4.81   0.51  -1.53
56555  -4.34  -0.64   2.31
96786  -3.33  -3.34  -7.62

I want to calculate the absolute max value of each row in a new column that keeps negatives as negatives. The closest I've gotten is with the following:

df['new_column'] = df.abs().max(axis = 1)

new_column
3.09
4.81
4.34
7.62

But I need the new column to keep the negative signs—i.e. to look like this:

new_column
-3.09
 4.81
-4.34
-7.62

I've attempted a few things using abs().idxmax(), and am wondering if I need to find the location of the absolute max value, and then return the value in that location in the new column—just not sure how to do this. Thoughts?



Solution 1:[1]

Here's one way using two steps: First, find the absolute max. Then see if absolute max equals any values in the DataFrame using eq and use the output as the power of -1 to get the signs:

row_max = df.abs().max(axis=1)
df['new_column'] = row_max * (-1) ** df.ne(row_max, axis=0).all(axis=1)

Another option is to use mask to choose values:

df['columns'] = df.max(axis=1).mask(lambda x: x < row_max, -row_max)

Output:

          a     b     c  new_column
124   -3.09 -0.38  2.34       -3.09
2359   4.81  0.51 -1.53        4.81
56555 -4.34 -0.64  2.31       -4.34
96786 -3.33 -3.34 -7.62       -7.62

Solution 2:[2]

I like the original idea you thought of, keeping with the theme:

# setup

data = {'a': [-3.09, 4.81, -4.34, -3.33],
        'b': [-.38, .51, -.64, -3.34],
        'c': [2.34, -1.53, 2.31, -7.62]}

df = pd.DataFrame(data, index= [124, 2359,56555,96786])

instead of:

df['new_column'] = df.abs().max(axis = 1)

let's change it to return the column instead of actual value:

max_col = df.abs().idxmax(axis = 1)

from there we can just iterate over it with enumerate for the row number and set it as the new column:

df['new_column'] = [df.loc[row,col] for row, col in zip(df.index, max_col)]

results:

          a     b     c  new_column
124   -3.09 -0.38  2.34       -3.09
2359   4.81  0.51 -1.53        4.81
56555 -4.34 -0.64  2.31       -4.34
96786 -3.33 -3.34 -7.62       -7.62

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2