将正则表达式应用于数据框的所有列的 Pythonic 方式
Posted
技术标签:
【中文标题】将正则表达式应用于数据框的所有列的 Pythonic 方式【英文标题】:Pythonic way of applying regex to all columns of dataframe 【发布时间】:2018-09-24 04:55:26 【问题描述】:我有一个包含所有列中的关键字和值的数据框。请参见下面的示例。
我想将正则表达式应用于所有列。所以我使用 for 循环并应用正则表达式:
for i in range (1,maxExtended_Keywords):
temp = 'extdkey_' + str(i)
Extended_Keywords[temp] = Extended_Keywords[temp].str.extract(":(.*)",expand=True)
我得到了想要的最终结果。那里没有问题。
但是,只是古玩有一种 pythonic 方式将正则表达式应用于整个数据帧,而不是使用 for 循环并应用于列。
谢谢,
【问题讨论】:
piRSqured 的回答非常好。一般来说,我认为循环遍历 Dataframe columns 没有问题。不过,您可能希望将循环替换为for c in Extended_Keywords.columns
。
更多 @AmiTavory 的观点,通常,数据帧没有非常多的列,我已经看到应用超过 10 列的情况比为了一些整体矢量化解决方案的目的而重新整形更快。跨度>
【参考方案1】:
将pandas.DataFrame.replace
与regex=True
一起使用
df.replace('^.*:\s*(.*)', r'\1', regex=True)
请注意,我的模式使用括号来捕获 ':'
之后的部分,并使用原始字符串 r'\1'
来引用该捕获组。
MCVE
df = pd.DataFrame([
[np.nan, 'thing1: hello'],
['thing2: world', np.nan]
], columns=['extdkey1', 'extdkey2'])
df
extdkey1 extdkey2
0 NaN thing1: hello
1 thing2: world NaN
df.replace('^.*:\s*(.*)', r'\1', regex=True)
extdkey1 extdkey2
0 NaN hello
1 world NaN
【讨论】:
非常好。有点奇怪,这不需要.str
构造,不是吗?
str
访问器适用于 Series
,这适用于整个 DataFrame。
你是对的,但是,假设为了保持一致,我猜可能还有一个 DataFrame.str
访问器。但也许我只是不明白逻辑,反正它是尼特。
那太好了!更奇怪的是,Series 有一个 replace
方法以及 str.replace
,它们的行为略有不同。
如果投反对票的人愿意,我将不胜感激。【参考方案2】:
你可以使用applymap,它会为dataframe中的每个元素应用一些函数,对于这个问题你可以这样做:
func = lambda x: re.findall('^.*:\s*(.*)', x)[0] if re.findall('^.*:\s*(.*)', str(x)) else x
df.applymap(func)
注意:由于效率问题,请避免将 applymap 用于大型数据帧。
【讨论】:
以上是关于将正则表达式应用于数据框的所有列的 Pythonic 方式的主要内容,如果未能解决你的问题,请参考以下文章