2017-08-29 34 views
2

我想过滤掉包含数据框中多列的特定值的行。筛选包含列中某些值的行

E.g

code tag number floor note 
1 1111 * **  34  no 
2 2323 7 899  7  no 
3 3677 # 900 11  no 
4 9897 10 134 *  no 
5 # # 566 11  no 
6 3677 55 908 11  no 

我想筛选出所有行包含#,*,**列码,标签,编号,楼层。

我想什么是

code tag number floor note 
1 1111 * **  34  no 
3 3677 # 900 11  no 
4 9897 10 134 *  no 
5 # # 566 11  no 

我试图用ISIN方法在数据帧,但它确实有一列工作,但在多列不起作用。谢谢!

回答

1

选项1
假设没有其他已存在的pir

df[df.replace(['#', '*', '**'], 'pir').eq('pir').any(1)] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 

选项2
令人讨厌的numpy broa dcasting。快在第一,但平方缩放

df[(df.values[None, :] == np.array(['*', '**', '#'])[:, None, None]).any(0).any(1)] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 

选项3
较少令人厌恶np.in1d

df[np.in1d(df.values, ['*', '**', '#']).reshape(df.shape).any(1)] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 

选项4
多年来与顶端

df[list(
    map(bool, 
     map({'*', '**', '#'}.intersection, 
      map(set, 
       zip(*(df[c].values.tolist() for c in df))))) 
)] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 
+0

哦,快点。Brb撤消一些投票。 –

1

我想你需要applyisinany布尔索引:

list = ['#','*','**'] 
cols = ['code','tag','number','floor'] 
df[df[cols].apply(lambda x: x.isin(list).any(), axis=1)] 

输出:

code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 
1

您也可以使用df.applymap

s = {'*', '**', '#'} 
df[df.applymap(lambda x: x in s).max(1)] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 

PIR suggested一个疯狂的(!但它的工作原理)替代:

df[df.apply(set, 1) & {'*', '**', '#'}] 

    code tag number floor note 
1 1111 *  ** 34 no 
3 3677 # 900 11 no 
4 9897 10 134  * no 
5  # # 566 11 no 
+1

@piRSquared因为它的工作原因而Re然心动。如果你没有问题,可以添加它作为答案? –