从不同的列中取绝对值最大值并过滤NaN(Python)

12

这是我的尝试。例如

df = pd.DataFrame({'a':[5,0,1,np.nan], 'b':[np.nan,1,4,3], 'c':[-3,-2,0,0]})
df.dropna(axis=1).max(axis=1,key=abs)

虽然过滤掉了NaN值,但是得到了绝对值最高的0或负数代替。

结果应该是一个列。

5
-2
4
3

当您执行 dropna 操作时,所有带有 NaN 值的列都将被丢弃,只剩下 c 列。 - Anton Protopopov
好的。无论如何,如果我使用df.max(axis=1,key=abs),它不会取绝对值的最大值,而只是最大的正数。 - gis20
5个回答

14

我解决了它。

maxCol=lambda x: max(x.min(), x.max(), key=abs)
df.apply(maxCol,axis=1)

这个解决方案可以工作,但是速度真的很慢...有更快的解决方案吗? - Alon Gouldman
我该如何修改代码,使其获取绝对最小值?我尝试使用了替换max为min的方法,即 min(x.min(),x.max(),key=abs) ,但这并没有起作用。 - Andrew Hamel
@AlonGouldman 如果你遇到性能问题,我的下面的答案应该更有效率。 - Brendan
@AndrewHamel 在下面我的回答中用 min() 替换 max(),它应该可以工作。 - Brendan
@Brendan,我想(也是OP想)保留负值。你的方法会将它们转换为正数。 - Alon Gouldman
@AlonGouldman 很好的澄清!在这种情况下,我建议使用 df.idxmax() 来获取最大值的索引,然后使用这些索引来选择原始数据框中的原始值。这种方法应该仍然优于任何应用操作。 - Brendan

8
最直接和高效的方法是将值转换为绝对值,然后找到最大值。Pandas支持使用简单的语法(absmax)实现此功能,不需要昂贵的apply操作:
df.abs().max()

max() 接受一个 axis 参数,可用于指定是在行还是列上计算最大值。


3
这并不能回答所提出的问题,因为它删除了负值。 - DataMan

4
你可以在平方数据上使用np.nanargmax
>>> df.values[range(df.shape[0]),np.nanargmax(df**2,axis=1)]
array([ 5., -2.,  4.,  3.])

1
df = df.fillna(0)
l = df.abs().values.argmax(axis=1)
pd.Series([df.values[i][l[i]] for i in range(len(df.values))])

In [532]: pd.Series([df.values[i][l[i]] for i in range(len(df.values))])
Out[532]:
0    5
1   -2
2    4
3    3
dtype: float64

一行代码:
pd.Series([df.values[i][df.fillna(0).abs().values.argmax(axis=1)[i]] for i in range(len(df.values))])

-1

由于我的声望分数较低,我想在 gis20 的回答和 Andrew Hamel 的问题中添加关于绝对最小值的内容:

minCol=lambda x: min(x, key=abs)
minCol=lambda x: min([abs(value) for value in x])  

对于我的数据来说是有效的,但是它无法处理 np.nan。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接