我有一个具有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
...
请注意,有一个额外的列总计,不应该包含在此过滤中(顾名思义,应用该过滤后,我们会将所有剩余行的总数相加)< / p>
到目前为止,我一直在使用较少的列的简单方法就是使用这样的方法:
df[df.eval('COL1 >= 1 & COL1 <= 5 | COL2 >= 1 & COL2 <= 5')]
但是,当处理数百个列时,这变得不切实际(并且还需要大量键入!)
我想知道在这里使用什么正确的方法。我已经开始为上述表达式添加更多条件,但是当达到30列时,我开始出现堆栈溢出或仅仅是内存错误。
我还尝试过使用其他“技巧”,例如将表达式重写为:
df[df.eval('~(COL1 != COL1 & COL2 != COL2)')]
但这又无济于事。
同样理想的是,如果可能的话,我想使用一种简单的方法在字符串中定义一个布尔表达式,因为这样的想法是允许最终用户为此过滤定义自定义表达式。
答案 0 :(得分:1)
比较所有列,并按DataFrame.any
检查每行是否至少有True
:
#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