繁体   English   中英

DataFrame中列的子集上的逻辑OR

[英]Logical OR on a subset of columns in a DataFrame

我想得到所有行(至少)df [mylist]中的一列包含True。

我现在正在做:

df = df[ df[mylist[0]] | df[mylist[1]] | df[mylist[2]] ]

其中mylist是与df列相关的字符串列表。 但我想为任何长度的mylist做这个。

我能想到的唯一方法是循环遍历mylist并为其中的每个元素创建一个新的数据帧,然后合并/ concat或其他任何内容。 但这对我来说并不是很聪明。

有没有更好的办法?

以LondonRob的答案为基础,您可以使用

df.loc[df[mylist].any(axis=1)]

调用DataFrame的any方法都比使用apply更好地执行每行一次调用Python的内置any函数。

或者您可以使用np.logical_or.reduce

df.loc[np.logical_or.reduce(df[mylist], axis=1)]

对于大型DataFrame,使用np.logical_or可能会更快:

In [30]: df = pd.DataFrame(np.random.binomial(1, 0.1, size=(100,300)).astype(bool))

In [31]: %timeit df.loc[np.logical_or.reduce(df, axis=1)]
1000 loops, best of 3: 261 µs per loop

In [32]: %timeit df.loc[df.any(axis=1)]
1000 loops, best of 3: 636 µs per loop

In [33]: %timeit df[df.apply(any, axis=1)]
100 loops, best of 3: 2.13 ms per loop

请注意, df.any具有额外的功能,例如跳过NaN的功能。 在这种情况下,如果列是布尔值,则不能有任何NaN(因为NaN是浮点值)。 所以np.logical_or.reduce更快。


import numpy as np
import pandas as pd
np.random.seed(2014)
df = pd.DataFrame(np.random.binomial(1, 0.1, size=(10,3)).astype(bool), 
                  columns=list('ABC'))
print(df)
#        A      B      C
# 0  False  False  False
# 1   True  False  False
# 2  False  False  False
# 3   True  False  False
# 4  False  False  False
# 5  False  False  False
# 6  False   True  False
# 7  False  False  False
# 8  False  False  False
# 9  False  False  False

mylist = list('ABC')
print(df[ df[mylist[0]] | df[mylist[1]] | df[mylist[2]] ])
print(df.loc[df[mylist].any(axis=1)])
print(df.loc[np.logical_or.reduce(df[mylist], axis=1)])

产生至少有一列为True的行:

       A      B      C
1   True  False  False
3   True  False  False
6  False   True  False

使用内置于any函数的python,有一种简单的方法:

In []: mylist
Out[]: ['A', 'B']

In []: df
Out[]: 
       A      B      C
0  False  False  False
1   True  False  False
2  False  False  False
3   True  False  False
4  False  False  False
5  False  False  False
6  False   True  False
7  False  False  False
8  False  False  False
9  False  False  False

您可以使用axis=1df行中apply any函数。 在这种情况下,我只会将any一个应用于列的子集:

In []: df[mylist].apply(any, axis=1)
Out[]: 
0    False
1     True
2    False
3     True
4    False
5    False
6     True
7    False
8    False
9    False
dtype: bool

这为我们提供了选择行的完美方式:

In []: df[df[mylist].apply(any, axis=1)]
Out[]: 
       A      B      C
1   True  False  False
3   True  False  False
6  False   True  False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM