首页 > 解决方案 > 过滤具有多个(> 100)列条件的熊猫行

问题描述

我有一个包含 20K 列的数据框,我需要通过应用超过 400 列的条件来过滤特定的行:

        COL1  COL2 ... COL400 total
  0      1.0  5.0      3.0    1.21
  1      1.0  NaN      NaN    4.33
  2      NaN  NaN      NaN    1.00
  3      NaN  2.0      1.0    0.12
  4      NaN  NaN      NaN    0.00
  5      1.0  3.0      4.0    3.39
  ...

我的需要是在这 400 列中的至少一列中保留至少包含[1, 5] 之间的 1 个数值的行:

        COL1  COL2 ... COL400 total
  0      1.0  5.0      3.0    1.21
  1      1.0  NaN      NaN    4.33
  3      NaN  2.0      1.0    0.12
  5      1.0  3.0      4.0    3.39
  ...

请注意,有一个额外的列总计,不应包含在此过滤中(顾名思义,在应用过滤后,我们将所有剩余行的总计相加)

到目前为止,我一直用于较少列的天真的方法一直在使用这样的东西:

df[df.eval('COL1 >= 1 & COL1 <= 5 | COL2 >= 1 & COL2 <= 5')]

但是在处理数百列时,这变得不切实际(并且还需要大量输入!)

我想知道在这里使用的正确方法是什么。我已经开始向上述表达式添加更多条件,但是当达到 30 列时,我开始出现堆栈溢出或只是内存错误。

我还尝试过使用其他“技巧”,例如重写表达式,例如:

df[df.eval('~(COL1 != COL1 & COL2 != COL2)')]

但这又无济于事。

同样理想的是,如果可能,我想使用一种简单的方法在字符串中定义布尔表达式,因为这个想法是允许最终用户为此过滤定义自定义表达式。

标签: pandas

解决方案


True比较所有列并检查每行是否至少有一个DataFrame.any

#check values in all columns
df = df[((df >= 1) & (df <= 5)).any(axis=1)]
#check values in columns specified in list
#cols = ['COL1','COL2', ...]
#df = df[((df[cols] >= 1) & (df[cols] <= 5)).any(axis=1)]

print (df)
   COL1  COL2  COL400
0   1.0   5.0     3.0
1   1.0   NaN     NaN
3   NaN   2.0     1.0
5   1.0   3.0     4.0

推荐阅读