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
Ocaml function to output max absolute value of a list.
Since this is for school, I'd rather try to help you think about this than just give you the answer. Let's look at this Socratically.
-
What's
absolute_valuesupposed to do? In particular, what makes it different fromabs? -
You have a comment noting that the type of
absolute_valueisint -> int. But you said you're "able to get the absolute value of a list". What does that mean? -
What's the type of
my_max? -
Finally, what's the type of
List.map?
Sort a column of values by their absolute value
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