2

我有一个带有数字值的熊猫数据框。如何遍历行并返回单元格值满足阈值的列名(在这种情况下,假设为 .05)?

pandas 数据框有 10K 行和 700 列。理想情况下,我希望返回一个字典,如下所示。

MWE

import pandas as pd
import numpy as np

np.random.seed(0)

df = pd.DataFrame(
    np.random.randint(0,10,size=(8, 7))/100, 
    columns=list('ABCDEFG'), 
    index = ['Dog', "Cat", 'Pig', 'Horse', 'Fish', 'Chicken', 'Squid', 'Cheetah']
)

屈服

   A     B     C     D     E     F     G
----  ----  ----  ----  ----  ----  ----
0.05  0     0.03  0.03  0.07  0.09  0.03
0.05  0.02  0.04  0.07  0.06  0.08  0.08
0.01  0.06  0.07  0.07  0.08  0.01  0.05
0.09  0.08  0.09  0.04  0.03  0     0.03
0.05  0     0.02  0.03  0.08  0.01  0.03
0.03  0.03  0.07  0     0.01  0.09  0.09
0     0.04  0.07  0.03  0.02  0.07  0.02
0     0     0.04  0.05  0.05  0.06  0.08

期望的输出

{
   'Dog': ['A', 'E', 'F'], 
    "Cat": ['A', 'D', 'E', 'F', 'G'], 
    'Pig': ['B', 'C', 'D', 'E', 'G'], 
    'Horse': ['A', "B", 'C'], 
    'Fish': ['A', 'E'], 
    'Chicken': ['C', 'F', 'G'], 
    'Squid': ['C', 'F'], 
    'Cheetah': ['D', 'E', 'F', 'G']
}
4

3 回答 3

3

这可以通过一个dot产品来实现:

thresh = .05
df.ge(thresh).dot(df.columns+',').str.rstrip(",").str.split(",").to_dict()

{'Dog': ['A', 'E', 'F'],
 'Cat': ['A', 'D', 'E', 'F', 'G'],
 'Pig': ['B', 'C', 'D', 'E', 'G'],
 'Horse': ['A', 'B', 'C'],
 'Fish': ['A', 'E'],
 'Chicken': ['C', 'F', 'G'],
 'Squid': ['C', 'F'],
 'Cheetah': ['D', 'E', 'F', 'G']}
于 2021-04-06T19:07:05.217 回答
3

您可以在此处将字典理解与布尔索引一起使用。

m = df.ge(0.05).values
out = {k: df.columns[m[i]].tolist() for i, k in enumerate(df.index)}

{'Dog': ['A', 'E', 'F'],
 'Cat': ['A', 'D', 'E', 'F', 'G'],
 'Pig': ['B', 'C', 'D', 'E', 'G'],
 'Horse': ['A', 'B', 'C'],
 'Fish': ['A', 'E'],
 'Chicken': ['C', 'F', 'G'],
 'Squid': ['C', 'F'],
 'Cheetah': ['D', 'E', 'F', 'G']}

Timeit 结果:基准设置

np.random.seed(0)
vals = np.random.rand(10_000, 700)
df_bench = pd.DataFrame(vals)
df_bench.columns = df_bench.columns.astype(str)

输出:

# @anky's answer
In [49]: %timeit df_bench.ge(thresh).dot(df_bench.columns+',').str.rstrip(",").s
    ...: tr.split(",").to_dict()                                                
1.36 s ± 50.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# @My answer
In [50]: %%timeit 
    ...: m = df_bench.ge(0.05).values 
    ...: out = {k: df_bench.columns[m[i]].tolist() for i, k in enumerate(df_benc
    ...: h.index)} 
    ...:  
    ...:                                                                        
167 ms ± 3.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# @Amit's answer
In [51]: %timeit df_bench.apply(lambda x: list(x[x>=0.05].index), axis = 1).to_d
    ...: ict()                                                                  

4.08 s ± 2.31 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

测试相等性所有解决方案都给出相同的输出。

于 2021-04-06T19:26:16.797 回答
2

采用:

output = df.apply(lambda x: list(x[x>=0.05].index), axis = 1).to_dict()

输出:

{'Dog': ['A', 'E', 'F'], 
'Cat': ['A', 'D', 'E', 'F', 'G'], 
'Pig': ['B', 'C', 'D', 'E', 'G'], 
'Horse': ['A', 'B', 'C'], 
'Fish': ['A', 'E'], 
'Chicken': ['C', 'F', 'G'], 
'Squid': ['C', 'F'], 
'Cheetah': ['D', 'E', 'F', 'G']}
于 2021-04-06T19:09:50.010 回答