【问题标题】:Selecting all column names where value is greater than another column in pandas选择值大于熊猫中另一列的所有列名
【发布时间】:2017-08-29 09:15:49
【问题描述】:

我试图在熊猫数据框中查找每列的列名,其中值大于另一列的值。

例如,如果我有以下数据框:

   A  B  C  D  threshold
0  1  3  3  1  2
1  2  3  6  1  5
2  9  5  0  2  4

对于每一行,我想返回值大于阈值的列的名称,所以我会:

0: B, C
1: C
2: A, B

任何帮助将不胜感激!

【问题讨论】:

  • 一种方法是使用apply。
  • @FClubb 如果您有大量数据,您可能想查看我的解决方案,它比其他解决方案快一个数量级以上

标签: python pandas


【解决方案1】:

如果您想大幅提高速度,可以使用 NumPy 的矢量化 where 函数。

s = np.where(df.gt(df['threshold'],0), ['A, ', 'B, ', 'C, ', 'D, ', ''], '')
pd.Series([''.join(x).strip(', ') for x in s])

0    B, C
1       C
2    A, B
dtype: object

使用 100,000 行的数据帧时,与 @jezrael 和 MaxU 解决方案相比,速度提高了一个数量级以上。这里我先创建测试DataFrame。

n = 100000
df = pd.DataFrame(np.random.randint(0, 10, (n, 5)), 
                  columns=['A', 'B', 'C', 'D', 'threshold'])

时间

%%timeit
>>> s = np.where(df.gt(df['threshold'],0), ['A, ', 'B, ', 'C, ', 'D, ', ''], '')
>>> pd.Series([''.join(x).strip(', ') for x in s])
280 ms ± 5.29 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
>>> df1 = df.drop('threshold', 1).gt(df['threshold'], 0)
>>> df1 = df1.apply(lambda x: ', '.join(x.index[x]),axis=1)
3.15 s ± 82.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
>>> x = df.drop('threshold',1)
>>> x.T.gt(df['threshold']).agg(lambda c: ', '.join(x.columns[c]))
3.28 s ± 145 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    【解决方案2】:

    你可以使用:

    df1 = df.drop('threshold', 1).gt(df['threshold'], 0)
    df1 = df1.apply(lambda x: ', '.join(x.index[x]),axis=1)
    print (df1)
    0    B, C
    1       C
    2    A, B
    dtype: object
    

    类似的解决方案:

    df1 = df.drop('threshold', 1).gt(df['threshold'], 0).stack().rename_axis(('a','b'))
            .reset_index(name='boolean')
    a = df1[df1['boolean']].groupby('a')['b'].apply(', '.join).reset_index()
    print (a)
       a     b
    0  0  B, C
    1  1     C
    2  2  A, B
    

    【讨论】:

    • 这正是我想要的,非常感谢!
    【解决方案3】:

    你可以这样做:

    In [99]: x = df.drop('threshold',1)
    
    In [100]: x
    Out[100]:
       A  B  C  D
    0  1  3  3  1
    1  2  3  6  1
    2  9  5  0  2
    
    In [102]: x.T.gt(df['threshold']).agg(lambda c: ', '.join(x.columns[c]))
    Out[102]:
    0    B, C
    1       C
    2    A, B
    dtype: object
    

    【讨论】:

      猜你喜欢
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      • 2018-06-25
      • 2018-05-05
      • 2018-02-18
      • 2020-03-12
      相关资源
      最近更新 更多