Python Pandas - 根据列表删除多个值

时间:2017-04-24 19:12:59

标签: python pandas

我试图从模糊匹配列表中项目的数据框中删除值。

我有一个类似于:

的数据框(test_df)
   id          email         created_at      
0  1   son@mail_a.com   2017-01-21 18:19:00  
1  2   boy@mail_b.com   2017-01-22 01:19:00  
2  3  girl@mail_c.com   2017-01-22 01:19:00 

我有一个包含几百个电子邮件域名的列表,我正在从一个类似于以下内容的txt文件中读取:

mail_a.com
mail_d.com
mail_e.com

我尝试使用以下方式从数据框中删除包含匹配电子邮件域的任何行:

email_domains = open('file.txt', 'r')
to_drop = email_domains.read().splitlines()    
dropped_df = test_df[~test_df['email'].isin(to_drop)]
    print(test_df)

因此,结果应如下所示:

   id          email         created_at       
0  2   boy@mail_b.com   2017-01-22 01:19:00  
1  3  girl@mail_c.com   2017-01-22 01:19:00 

但第一行是" son@mail_a.com"没有丢弃。有什么建议?

4 个答案:

答案 0 :(得分:3)

从电子邮件中解析域名非常容易,因此我们可以先使用.str.split('@')解析域名,然后使用isin()方法进行检查:

In [12]: df[~df.email.str.split('@').str[1].isin(domains.domain)]
Out[12]:
   id            email           created_at
1   2   boy@mail_b.com  2017-01-22 01:19:00
2   3  girl@mail_c.com  2017-01-22 01:19:00

其中:

In [13]: domains
Out[13]:
       domain
0  mail_a.com
1  mail_d.com
2  mail_e.com

答案 1 :(得分:3)

isin查找完全匹配。您的情况更适合endswithcontains

df[~df['email'].str.endswith(tuple(to_drop))]
Out: 
   id            email           created_at
1   2   boy@mail_b.com  2017-01-22 01:19:00
2   3  girl@mail_c.com  2017-01-22 01:19:00
df[~df['email'].str.contains('|'.join(to_drop))]
Out: 
   id            email           created_at
1   2   boy@mail_b.com  2017-01-22 01:19:00
2   3  girl@mail_c.com  2017-01-22 01:19:00

答案 2 :(得分:0)

您可以使用if (objects.count)apply字符串并将其用于split

isin

结果

print test_df[~test_df['email'].apply(lambda x: x.split('@')[1]).isin(to_drop)]

答案 3 :(得分:0)

又一个答案......这是一个单行:

exclude = ['mail_a.com','mail_d.com','mail_e.com']
df[df.apply(lambda x: all([x['email'].rfind(ex) < 0 for ex in exclude]), axis=1)]
# OUTPUT
# Out[50]:
#              created_at            email  id
# 1   2017-01-22 01:19:00   boy@mail_b.com   2
# 2   2017-01-22 01:19:00  girl@mail_c.com   3

如果找不到模式,我在这里使用rfind返回-1。