熊猫选择列中的值不以字符串开头的行

Posted

技术标签:

【中文标题】熊猫选择列中的值不以字符串开头的行【英文标题】:Pandas select rows where a value in a columns does not starts with a string 【发布时间】:2018-08-15 16:30:39 【问题描述】:

我有一个数据,我需要过滤掉任何以某个值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 的解决方案有何不同?当你有 for 循环构造而不是像 map 或 apply 这样的系列上的操作时,它如何比较性能?如果我理解正确, contains() 不会被 startwith() 专门查看字符串开头的位置所困扰。这是否意味着 ^ 表示 contains() 做什么?从头开始? | 是该方法的另一个特殊字符还是被视为 逻辑 OR?如果你不介意分享,我真的很想学习这个。谢谢

【问题讨论】:

【参考方案1】:

你可以使用startswith,前面的~会从in转换成not in

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

【讨论】:

【参考方案2】:

使用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

【讨论】:

df[~df['Name'].str.contains('^' + '|^'.join(prefixes))] 可以吗?

以上是关于熊猫选择列中的值不以字符串开头的行的主要内容,如果未能解决你的问题,请参考以下文章

python 获取不以某些字母开头的列中的值

根据“如果单元格中的字符串”条件删除熊猫列中的行

如何获取熊猫数据框中的行,列中具有最大值并保留原始索引?

如何删除所有不以某些字符开头的行?

在给定列中拆分字符串值(熊猫)

比较熊猫数据框列中的值时出现类型错误