如何在Pandas DataFrame中获取第二大行值的列名

如何在Pandas DataFrame中获取第二大行值的列名,第1张

如何在Pandas DataFrame中获取第二大行值的列名

一种方法是使用来选择每一行中的两个最大元素

Series.nlargest
并使用来找到对应于最小元素的列
Series.idxmin

In [45]: df['value'] = df.T.apply(lambda x: x.nlargest(2).idxmin())In [46]: dfOut[46]:      A   B    C   D valuea1  1.1   2  3.3   4     Ca2  2.7  10  5.4   7     Da3  5.3   9  1.5  15     B

值得注意的是捡

Series.idxmin
Dataframe.idxmin
可以有所作为的性能代价:

df = pd.Dataframe(np.random.normal(size=(100, 4)), columns=['A', 'B', 'C', 'D'])%timeit df.T.apply(lambda x: x.nlargest(2).idxmin()) # 39.8 ms ± 2.66 ms%timeit df.T.apply(lambda x: x.nlargest(2)).idxmin() # 53.6 ms ± 362 µs

编辑:添加到@jpp的答案,如果性能很重要,则可以通过使用Numba,像编写C一样编写代码并将其编译来大大提高速度:

from numba import njit, prange@njitdef arg_second_largest(arr):    args = np.empty(len(arr), dtype=np.int_)    for k in range(len(arr)):        a = arr[k]        second = np.NINF        arg_second = 0        first = np.NINF        arg_first = 0        for i in range(len(a)): x = a[i] if x >= first:     second = first     first = x     arg_second = arg_first     arg_first = i elif x >= second:     second = x     arg_second = i        args[k] = arg_second    return args

让我们比较形状分别为

(1000, 4)
和的两组数据的不同解决方案
(1000, 1000)

df = pd.Dataframe(np.random.normal(size=(1000, 4)))%timeit df.T.apply(lambda x: x.nlargest(2).idxmin())     # 429 ms ± 5.1 ms%timeit df.columns[df.values.argsort(1)[:, -2]]          # 94.7 µs ± 2.15 µs%timeit df.columns[np.argpartition(df.values, -2)[:,-2]] # 101 µs ± 1.07 µs%timeit df.columns[arg_second_largest(df.values)]        # 74.1 µs ± 775 nsdf = pd.Dataframe(np.random.normal(size=(1000, 1000)))%timeit df.T.apply(lambda x: x.nlargest(2).idxmin())     # 1.8 s ± 49.7 ms%timeit df.columns[df.values.argsort(1)[:, -2]]          # 52.1 ms ± 1.44 ms%timeit df.columns[np.argpartition(df.values, -2)[:,-2]] # 14.6 ms ± 145 µs%timeit df.columns[arg_second_largest(df.values)]        # 1.11 ms ± 22.6 µs

在最后一种情况下,通过使用

@njit(parallel=True)
并替换为外环,我可以挤出更多一点并将基准降低到852 µs
for k inprange(len(arr))



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5021295.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-15
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存