jus*_*nvf 144 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
Run Code Online (Sandbox Code Playgroud)
我想将行过滤为f使用正则表达式开头的行.先去:
In [213]: foo.b.str.match('f.*')
Out[213]:
0 []
1 ()
2 ()
3 []
Run Code Online (Sandbox Code Playgroud)
这不是太有用了.但是这会得到我的布尔索引:
In [226]: foo.b.str.match('(f.*)').str.len() > 0
Out[226]:
0 False
1 True
2 True
3 False
Name: b
Run Code Online (Sandbox Code Playgroud)
所以我可以通过以下方式来限制:
In [229]: foo[foo.b.str.match('(f.*)').str.len() > 0]
Out[229]:
a b
1 2 foo
2 3 fat
Run Code Online (Sandbox Code Playgroud)
这让我人为地把一组人放进了正则表达式,看起来可能不是那种干净的方式.有一个更好的方法吗?
wai*_*kuo 161
使用包含而不是:
In [10]: df.b.str.contains('^f')
Out[10]:
0 False
1 True
2 True
3 False
Name: b, dtype: bool
Run Code Online (Sandbox Code Playgroud)
小智 16
使用dataframe进行多列搜索:
frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')]
Run Code Online (Sandbox Code Playgroud)
Erk*_*rin 15
已有字符串处理功能Series.str.startswith().
你应该试试foo[foo.b.str.startswith('f')].
结果:
a b
1 2 foo
2 3 fat
Run Code Online (Sandbox Code Playgroud)
我想你的期望.
感谢@ 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)]
Run Code Online (Sandbox Code Playgroud)
使用 Python 内置的编写 lambda 表达式的功能,我们可以通过任意正则表达式操作进行过滤,如下所示:
import re
# with foo being our pd dataframe
foo[foo['b'].apply(lambda x: True if re.search('^f', x) else False)]
Run Code Online (Sandbox Code Playgroud)
通过使用 re.search,您可以通过复杂的正则表达式样式查询进行过滤,在我看来,这更强大。(因为str.contains相当有限)
另外值得一提的是:您希望字符串以小“f”开头。通过使用正则表达式,f.*您可以将 f 匹配到文本中的任意位置。通过使用该^符号,您明确声明您希望它位于内容的开头。所以使用^f可能是一个更好的主意:)
编写一个布尔函数来检查正则表达式并在列上使用apply
foo[foo['b'].apply(regex_function)]
Run Code Online (Sandbox Code Playgroud)