Pandas DataFrame:以绝对值选择行方式最大值

ibrsph3r  于 2023-08-01  发布在  其他
关注(0)|答案(3)|浏览(130)

我有一个只有数字数据的Dataframe:

[ In1]: df = pd.DataFrame(np.random.randn(5, 3).round(2), columns=['A', 'B', 'C'])
        df

[Out1]:         A       B       C
        0   -0.27    1.22    1.10
        1   -3.22    0.48   -1.64
        2    1.42    0.24   -0.12
        3   -1.12    0.44    0.23
        4    1.88   -0.38    0.62

字符串
如何为每行选择绝对值的最大值,同时保留符号?
在这种情况下,它将是:

0     1.22
1    -3.22
2     1.42
3    -1.12
4     1.88


我已经决定使用哪一列了:

[ In2]: loc_max = df.abs().idxmax(axis=1)
        loc_max

[Out2]: 
        0    B
        1    A
        2    A
        3    A
        4    A


性能很重要,因为我的实际数据框架很大。

解决方案比较:

下面的所有答案都将给予预期的结果。
在稍大的数据框架上进行性能比较:

df = pd.DataFrame(np.random.randn(1000, 100).round(2))

def numpy_argmax():
    idx_max = np.abs(df.values).argmax(axis=1)
    val = df.values[range(len(df)), idx_max]
    return pd.Series(val, index=df.index)

def check_sign():
    row_max = df.abs().max(axis=1)
    return row_max * (-1) ** df.ne(row_max, axis=0).all(axis=1)

def loop_rows():
    return df.apply(lambda s: s[s.abs().idxmax()], axis=1)

def pandas_loc():
    s = df.abs().idxmax(axis=1)
    val = [df.loc[x, y] for x, y in zip(s.index, s)]
    return pd.Series(val, index=df.index)

%timeit numpy_argmax()
%timeit check_sign()
%timeit loop_rows()
%timeit pandas_loc()


结果如下:


的数据
像往常一样,在pandas幕布后面的numpy级别达到最佳性能。(如果这并不总是真的,请告诉我。

eqqqjvef

eqqqjvef1#

让我们在绝对值上使用argmax来找到最大绝对值的索引。然后使用这些索引从每一行中获取相应的值。

v = df.values
v[range(len(v)), np.abs(v).argmax(axis=1)]

个字符

dl5txlt9

dl5txlt92#

一个建立在你尝试的基础上的方法,使用numpy索引和numpy广播规则:

import pandas as pd

df = pd.DataFrame(np.random.randn(5, 3).round(2), columns=['A', 'B', 'C'])
idx_max = np.argmax( df.abs(), axis=1)
df.values[range(len(df)), idx_max]

字符串

pes8fvy9

pes8fvy93#

另一种可能的解决方案:

s = df.abs().idxmax(axis=1)
[df.loc[x, y] for x, y in zip(s.index, s)]

字符串

相关问题