The built-in max takes a key function, you can pass that as abs:
>>> max([3, 7, -10], key=abs)
-10
You can call abs again on the result to normalise the result:
>>> abs(max([3, 7, -10], key=abs))
10
Answer from Moses Koledoye on Stack OverflowThe built-in max takes a key function, you can pass that as abs:
>>> max([3, 7, -10], key=abs)
-10
You can call abs again on the result to normalise the result:
>>> abs(max([3, 7, -10], key=abs))
10
max(max(a),-min(a))
It's the fastest for now, since no intermediate list is created (for 100 000 values):
In [200]: %timeit max(max(a),-min(a))
100 loops, best of 3: 8.82 ms per loop
In [201]: %timeit abs(max(a,key=abs))
100 loops, best of 3: 13.8 ms per loop
In [202]: %timeit max(map(abs,a))
100 loops, best of 3: 13.2 ms per loop
In [203]: %timeit max(abs(n) for n in a)
10 loops, best of 3: 19.9 ms per loop
In [204]: %timeit np.abs(a).max()
100 loops, best of 3: 11.4 ms per loop
python - How to find values with minimal absolute values in several columns ignoring NaNs? - Stack Overflow
math - Elegant mechanism to determine smallest magnitude number but preserve sign in Python - Stack Overflow
python - How to get the value with the smaller absolute value from a panda Series - Stack Overflow
vectorization - numpy: minimal absolute value above threshold - Stack Overflow
Let, df the dataframe with two columns, apply conditional absolute minimum over rows using axis=1
Here, x[np.argmin(x.abs())] checks the row index with absolute minimum and return the the original value with sign.
Also, we would need pd.isnull(x.min()) check for 'All-NaN slice encountered i.e when both the columns have NaN values.
In [3]: df.apply(lambda x: x.min() if pd.isnull(x.min()) else
x[np.argmin(x.abs())], axis=1)
Out[3]:
0 NaN
1 2
2 1
3 0
4 -1
5 -2
6 -3
7 -4
8 4
9 3
10 2
dtype: float64
OK, after reading and understanding your question and not being able to find a vectorised approach, we can define a custom function and call apply and pass each row.
So this will check if either column is null if so return the min value, it then compares the abs value of either column and then returns the column that has smallest abs value but the original value including sign:
In [269]:
def func(x):
if pd.isnull(x.a) or pd.isnull(x.b):
return x.min()
elif np.abs(x.a) < np.abs(x.b):
return x.a
else:
return x.b
df.apply(lambda row: func(row), axis = 1)
Out[269]:
0 NaN
1 2
2 1
3 0
4 -1
5 -2
6 -3
7 -4
8 4
9 3
10 2
dtype: float64