使用字典将多个字符串包含过滤器应用于pandas数据框

时间:2017-04-13 10:00:03

标签: python pandas filter

我需要根据字符串包含在多个列上设置一个过滤器,这将在dict column_filters中指定,而忽略使用toupper()的文本案例或沿着这些行的某些内容...例如

column_filters = {'COLUMN_1': ['drum', 'gui'], 'COLUMN_2': ['sta', 'kic']}

df = pd.DataFrame({'COLUMN_1': ['DrumSet', 'GUITAR', 'String', 'Bass', 'Violin'],
                   'COLUMN_2': ['STAND', 'DO', 'KICKSET', 'CAT', 'CELLO'],
                   'COLUMN_3': ['LOSER', 'LOVE', 'LICKING', 'STICK', 'BOLOGNA'])

基于COLUMN_FILTERS dict过滤的数据框:

         COLUMN_1   COLUMN_2    COLUMN_3
      0 DrumSet      STAND       LOSER
      1 GUITAR       DO          LOVE
      2 String       KICKSET     LICKING
      3 Bass         CAT         STICK
      4 Violin       CELLO       BOLOGNA

结果:

    COLUMN_1    COLUMN_2     COLUMN_3
0   DrumSet      STAND       LOSER
1   GUITAR       DO          LOVE
2   String       KICKSET     LICKING

1 个答案:

答案 0 :(得分:1)

我将dict值转换为正则表达式,方法是将所有字符串与'|'连接起来,然后使用str.contains过滤df:

In [50]:
for k in column_filters.keys():
    column_filters[k] = '|'.join(column_filters[k])
column_filters

Out[50]:
{'COLUMN_1': 'drum|gui', 'COLUMN_2': 'sta|kic'}

现在使用str.contains使用param case=False进行过滤:

In [51]:
df.loc[(df['COLUMN_1'].str.contains(column_filters['COLUMN_1'], case=False)) | (df['COLUMN_2'].str.contains(column_filters['COLUMN_2'], case=False))]

Out[51]:
  COLUMN_1 COLUMN_2
0  DrumSet    STAND
1   GUITAR       DO
2   String  KICKSET

<强>更新

确定有动态方法:

In [68]:
df[df.apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False)).any(axis=1)]

Out[68]:
  COLUMN_1 COLUMN_2
0  DrumSet    STAND
1   GUITAR       DO
2   String  KICKSET

我们可以看到没有布尔掩码,它正确匹配:

In [69]:
df.apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False))

Out[69]:
  COLUMN_1 COLUMN_2
0     True     True
1     True    False
2    False     True
3    False    False
4    False    False

更新2

再次回答您修改过的问题:

In [75]:
df[df[list(column_filters.keys())].apply(lambda x: x.str.contains('|'.join(column_filters[x.name]), case=False)).any(axis=1)]

Out[75]:
  COLUMN_1 COLUMN_2 COLUMN_3
0  DrumSet    STAND    LOSER
1   GUITAR       DO     LOVE
2   String  KICKSET  LICKING