问题:如何通过正则表达式过滤熊猫中的行
我想在其中一列上使用正则表达式干净地过滤数据框。
举一个人为的例子:
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
但是,这使我人为地将一组放入正则表达式中,并且似乎不是一种干净的方法。有一个更好的方法吗?
回答 0
使用包含代替:
In [10]: df.b.str.contains('^f')
Out[10]:
0 False
1 True
2 True
3 False
Name: b, dtype: bool
回答 1
已经有一个字符串处理功能 Series.str.startswith()
。你应该尝试foo[foo.b.str.startswith('f')]
。
结果:
a b
1 2 foo
2 3 fat
我认为您的期望。
另外,您可以使用包含和正则表达式选项。例如:
foo[foo.b.str.contains('oo', regex= True, na=False)]
结果:
a b
1 2 foo
na=False
是为了防止出现nan,null等值时出现错误
回答 2
使用数据框进行多列搜索:
frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')]
回答 3
这可能会有点晚,但是现在在Pandas中更容易做到。您可以调用match with as_indexer=True
以获得布尔结果。这是记录(与之间的差异沿match
和contains
)在这里。
回答 4
感谢您提供@ user3136169的出色答案,这是一个如何删除NoneType值的示例。
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)]
您也可以将regex添加为arg:
def regex_filter(val,myregex):
...
df_filtered = df[df['col'].apply(res_regex_filter,regex=myregex)]
回答 5
编写一个布尔函数来检查正则表达式并在列上使用apply
foo[foo['b'].apply(regex_function)]
回答 6
使用str
切片
foo[foo.b.str[0]=='f']
Out[18]:
a b
1 2 foo
2 3 fat