我想获取所有行(至少)在df [mylist]中的一列包含True。
我目前正在做:
df = df[ df[mylist[0]] | df[mylist[1]] | df[mylist[2]] ]
其中mylist是与的列有关的字符串列表df。但我想在不限长度的情况下进行此操作mylist。
我能想到的唯一方法是循环mylist并为其每个元素创建一个新的数据框,然后进行合并/合并或其他操作。但这对我来说并不聪明。
mylist
有没有更好的办法?
建立在LondonRob的答案上,您可以使用
df.loc[df[mylist].any(axis=1)]
与每行一次调用Python的内置函数any相比apply,调用DataFrame的方法将具有更好的性能any。
或者您可以使用np.logical_or.reduce:
np.logical_or.reduce
df.loc[np.logical_or.reduce(df[mylist], axis=1)]
对于大型DataFrame,使用起来np.logical_or可能更快:
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