如何使用&串联条件以过滤Pandas Dataframe?

时间:2019-05-24 05:42:26

标签: python pandas

我需要概括一个函数以在不同的数据框中使用它:

def existence(x):
    return df[df.isin([x]).any(1)]

我需要将其概括为一个接受可变数量参数的函数,例如:

existence([[x1],[x2],...,[xn]]):
    return df[df.isin([x1]).any(1) & df.isin([x2]).any(1) & ... & df.isin([xn]).any(1)]

isin()可以接受列表作为参数,但与列表的每个元素之间的“或”进行比较,显示甚至包含该列表元素的任何行。这就是为什么我在条件之间需要一个“&”的原因,我一直在尝试做类似的事情:

cond = [['A'],['B']]     ##isin only accept list items not str
df_diag[np.logical_and.reduce(df_diag.isin(cond).any(1))]

但是他没有表现出我的期望。

2 个答案:

答案 0 :(得分:2)

将列表理解用于按cond中的值进行循环:

df = pd.DataFrame({
        'A':list('Abcdef'),
         'B':[4,5,4,5,5,4],
         'E':[5,3,6,9,2,4],
         'F':list('BaabbA')
})

print (df)
   A  B  E  F
0  A  4  5  B
1  b  5  3  a
2  c  4  6  a
3  d  5  9  b
4  e  5  2  b
5  f  4  4  A

cond = [['A'],['B']]
m = np.logical_and.reduce([df.isin(x).any(1) for x in cond])
print (m)
[ True False False False False False]

m = (pd.concat([df.isin(x).any(1) for x in cond], axis=1)).all(axis=1)
print (m)
0     True
1    False
2    False
3    False
4    False
5    False
dtype: bool

如果在纯python中使用设置,则效果很好,只需将条件更改为['A','B']

m = df.apply(lambda x: set(['A','B']).issubset(x),axis=1)

答案 1 :(得分:1)

编辑2:作为jezrael's answer的替代方法,您可以使用:

df = pd.DataFrame({
    'A':list('Abcdef'),
    'B':[4,5,4,5,5,4],
    'E':[5,3,6,9,2,4],
    'F':list('BaaBbA')
})

def existence(df,columns,cond):
    return df[df[columns].apply(lambda x: 
                np.isin(np.array(cond).astype(str), x.astype(str).tolist()).all()
            ,axis=1)]

print(existence(df,df.columns,['A','B']))
print(existence(df,df.columns,[ 4,'a']))    # note the different types

产量:

   A  B  E  F
0  A  4  5  B

   A  B  E  F
2  c  4  6  a

然而,这需要通过.astype(str)来显式地强制执行dtype,因为此解决方案会在DataFrame上逐行遍历,请参见here