Python 如何按正则表达式筛选pandas中的行
我想在其中一列上使用正则表达式干净地过滤数据帧 举一个人为的例子:Python 如何按正则表达式筛选pandas中的行,python,regex,pandas,Python,Regex,Pandas,我想在其中一列上使用正则表达式干净地过滤数据帧 举一个人为的例子: In [210]: foo = pd.DataFrame({'a' : [1,2,3,4], 'b' : ['hi', 'foo', 'fat', 'cat']}) In [211]: foo Out[211]: a b 0 1 hi 1 2 foo 2 3 fat 3 4 cat 我想使用正则表达式将行筛选为以f开头的行。第一步: In [213]: foo.b.str.match('f.*'
In [210]: foo = pd.DataFrame({'a' : [1,2,3,4], 'b' : ['hi', 'foo', 'fat', 'cat']})
In [211]: foo
Out[211]:
a b
0 1 hi
1 2 foo
2 3 fat
3 4 cat
我想使用正则表达式将行筛选为以f
开头的行。第一步:
In [213]: foo.b.str.match('f.*')
Out[213]:
0 []
1 ()
2 ()
3 []
那不太有用。但是,这将获得布尔索引:
In [226]: foo.b.str.match('(f.*)').str.len() > 0
Out[226]:
0 False
1 True
2 True
3 False
Name: b
因此,我可以通过以下方式进行限制:
In [229]: foo[foo.b.str.match('(f.*)').str.len() > 0]
Out[229]:
a b
1 2 foo
2 3 fat
这让我人为地把一组人加入正则表达式,似乎这不是一个干净的方法。有更好的方法吗?改用:
使用dataframe进行多列搜索:
frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')]
可能有点晚了,但现在打电话给熊猫更容易做到这一点。解释
match
、fullmatch
和之间的差异包含
请注意,为了使用结果进行索引,请设置na=False
参数(或者True
如果希望在结果中包含nan)。已经有一个字符串处理函数Series.str.startswith()
。
您应该尝试foo[foo.b.str.startswith('f')]
结果:
a b
1 2 foo
2 3 fat
a b
1 2 foo
我想你期望的是什么
或者,您可以将contains与regex一起使用。例如:
foo[foo.b.str.contains('oo', regex= True, na=False)]
结果:
a b
1 2 foo
2 3 fat
a b
1 2 foo
na=False
是为了防止出现nan、null等错误。值编写一个布尔函数,检查正则表达式并在列上使用apply
foo[foo['b'].apply(regex_function)]
感谢@user3136169给出的好答案,下面是一个示例,说明如何删除非类型值
def regex_filter(val):
if val:
mo = re.search(regex,val)
if mo:
return True
else:
return False
else:
return False
df_filtered = df[df['col'].apply(regex_filter)]
您还可以将正则表达式添加为参数:
def regex_filter(val,myregex):
...
df_filtered = df[df['col'].apply(res_regex_filter,regex=myregex)]
使用str
slice
foo[foo.b.str[0]=='f']
Out[18]:
a b
1 2 foo
2 3 fat
如果你没有拘泥于正则表达式,foo[foo.b.str.startswith(“f”)]
会起作用。我认为foo[foo.b.str.match('(f.*)).str.len()>0]
是一个非常好的解决方案!比startswith更具可定制性和实用性,因为它包含了正则表达式的多功能性。这可能有点晚,但在新版本的pandas中,问题已经解决。行foo[foo.b.str.match('f.*')]
在pandas 0.24.2中对我有效。布尔值如何反转?找到它:是否可以只获取那些具有True的行?@shockwave您应该使用:df.loc[df.b.str.contains(“^f”),:]
@shockwave您也可以只使用df[df.b.str.contains(“^f”),:]
frame
?和'C:\test\test.txt'
?看起来你在回答一个不同的问题。框架是df。它与同一个问题有关,但它回答了如何在一行代码中过滤多个列(“filename”和“file_path”)。谢谢,正因为如此,我找到了一种通过任意谓词过滤列的方法。我对此进行了修改,它为我工作df[~df.CITY.str.contains(“~*”,regex=True,na=False)]
谢谢!这是一个很好的解决方案