将正则表达式应用于数据框的所有列的 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.replaceregex=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 方式的主要内容,如果未能解决你的问题,请参考以下文章

Pandas:将依赖于第三列的相同数据框的两列相乘

将不同的函数应用于按名称选择函数的数据框的列

在多列上迭代和应用正则表达式函数/str 计数

Pyspark - 一次聚合数据框的所有列[重复]

Pyspark:UDF 将正则表达式应用于数据帧中的每一行

如何使用 Python 将正则表达式应用于系列中的元素 [重复]