Pandas选择行中的值不以字符串

时间:2018-03-07 14:21:50

标签: python-3.x pandas anaconda jupyter-notebook

我有一个数据,我需要过滤掉任何以某个值开头的行 s - 强调复数:

数据下方与文件data.xlsx

中显示的数据完全相同
Name                Remains
GESDSRPPZ0161       TRUE
RT6000996           TRUE
RT6000994           TRUE
RT6000467           TRUE
RT6000431           TRUE
MCOPSR0034          FALSE
MCOPSR0033          FALSE

我需要能够返回一个数据框,其中名称不是 MCO,GE 等开头。

import pandas as pd
import numpy as np

### data
file = r'C:\Users\user\Desktop\data.xlsx'

data  = pd.read_excel(file, na_values = '')
data['name'] = data['name'].str.upper()

prefixes = ['IM%','JE%','GE%','GV%','CHE%','MCO%']

new_data = data.select(lambda x: x not in prefixes)


new_data.shape

最后一次调用返回与我开始时完全相同的数据集。

我试过了:

pandas select from Dataframe using startswith

但是如果字符串在别处(不仅仅是以)开头,它会排除数据

df = df[df['Column Name'].isin(['Value']) == False]

如果我确切知道有问题的字符串,上面的答案会有效,但是它会改变(常见部分是MCOxxxxx,GVxxxxxx,GExxxxx ......)

这个发生了同样的事情:

How to implement 'in' and 'not in' for Pandas dataframe

因为我必须传递的值必须准确。有没有办法使用与此处相同的逻辑(是否有像SQL这样的通配符的等价物?):

How do I select rows where a column value starts with a certain string?

感谢您的帮助!我们可以在下面展开吗?

@jezrael虽然我为了简单而选择了另一个解决方案(而且我对你的解决方案缺乏了解),但是我想请求一些解释。什么' ^' +' | ^' 在这段代码中做了什么?它与Wen的解决方案有什么不同?当你将循环结构与对像map或apply这样的系列上的操作相反时,它如何比较性能呢?如果我理解正确 contains()不会因为startswith()专门查看字符串的开头的位置而烦恼。这是不是意味着  ^表示要包含()做什么?从头开始?  并且 | 是该方法的另一个特殊字符,还是被视为逻辑OR ?如果你不介意分享,我真的想学习这个。感谢

2 个答案:

答案 0 :(得分:2)

您可以使用startswith,前面的~会从中转换为非

prefixes = ['IM','JE','GE','GV','CHE','MCO']

df[~df.Name.str.startswith(tuple(prefixes))]
Out[424]: 
        Name  Remains
1  RT6000996     True
2  RT6000994     True
3  RT6000467     True
4  RT6000431     True

答案 1 :(得分:1)

使用str.contains^一起开始字符串并按boolean indexing过滤:

prefixes = ['IM','JE','GE','GV','CHE','MCO']

pat = '|'.join([r'^{}'.format(x) for x in prefixes])
df = df[~df['Name'].str.contains(pat)]
print (df)
        Name  Remains
1  RT6000996     True
2  RT6000994     True
3  RT6000467     True
4  RT6000431     True

谢谢@Zero的另一个解决方案:

df = df[~df['Name'].str.contains('^' + '|^'.join(prefixes))]
print (df)
        Name  Remains
1  RT6000996     True
2  RT6000994     True
3  RT6000467     True
4  RT6000431     True