在熊猫数据框上应用正则表达式函数

Posted

技术标签:

【中文标题】在熊猫数据框上应用正则表达式函数【英文标题】:Apply a regex function on a pandas dataframe 【发布时间】:2018-02-17 04:41:58 【问题描述】:

我在 pandas 中有一个数据框,例如:

0                       1                   2
([0.8898668778942382    0.89533945283595]   0)
([1.2632564814188714    1.0207660696232244] 0)
([1.006649166957976     1.1180973832359227] 0)
([0.9653632916751714    0.8625538463644129] 0)
([1.038366333873932     0.9091449796555554] 0)

所有值都是字符串。我想删除所有特殊字符并转换为双精度。我想应用一个函数来删除所有特殊字符,除了点之外的

import re
re.sub('[^0-9.]+', '',x)

所以我想在数据框的所有单元格中应用它。我该怎么做?我找到了 df.applymap 函数,但我不知道如何将字符串作为参数传递。我试过了

def remSp(x): 
    re.sub('^[0-9]+', '',x)

df.applymap(remSp())

但我不知道如何将单元格传递给函数。有更好的方法吗?

谢谢

【问题讨论】:

通过remSp 不带(),参数是函数本身,而不是调用的结果 applymap 函数将对数据框中的每个项目调用 remSp 你传递的是寻找df.applymap(remSp),注意,你不想在传递之前调用函数,.applymap把函数当作一个参数。请注意,您可能希望以正则表达式模式将. 添加到您的组... 我试过这个 [ df.applymap(remSp) ]但是返回一个所有值都没有的数据框 @MichailN 是的,因为remSp 总是以您定义的方式返回None... 【参考方案1】:

为什么不能直接用正则表达式在df上使用默认替换方法,即

df = df.replace('[^\d.]', '',regex=True).astype(float)
0 1 2 0 0.889867 0.895339 0.0 1 1.263256 1.020766 0.0 2 1.006649 1.118097 0.0 3 0.965363 0.862554 0.0 4 1.038366 0.909145 0.0

这仍然比其他答案更快。

【讨论】:

Yes, this is better... nice job. 我试过这一行,它给了我以下错误:“无法将字符串转换为浮点数”有什么想法吗? 在此尝试删除.astype(float) 并使用.apply(lambda x : pd.to_numeric(x,errors='coerce'),1) 之后,错误可能是由于某些nan 或列中存在未知字符串。【参考方案2】:

使用applymap

In [814]: df.applymap(lambda x: re.sub(r'[^\d.]+', '', x)).astype(float)
Out[814]:
          0         1    2
0  0.889867  0.895339  0.0
1  1.263256  1.020766  0.0
2  1.006649  1.118097  0.0
3  0.965363  0.862554  0.0
4  1.038366  0.909145  0.0

使用transform

In [809]: df.transform(lambda x: x.str.replace(r'[^\d.]+', '')).astype(float)
Out[809]:
          0         1    2
0  0.889867  0.895339  0.0
1  1.263256  1.020766  0.0
2  1.006649  1.118097  0.0
3  0.965363  0.862554  0.0
4  1.038366  0.909145  0.0

【讨论】:

@COLDSPEED 尽管我喜欢一个班轮,但你的回答表现得更好,先生做得好! @MichailN Added benchmarks。说真的……一个班轮被高估了。 @COLDSPEED 有时风格比性能好,但无论如何你是对的 @MichailN 在我不得不直接闯入另一个人的答案之前,我的答案没有投票......说真的,......没有人喜欢循环或什么? :-( @cᴏʟᴅsᴘᴇᴇᴅ -- 我同意,我痴迷于表现自己;)【参考方案3】:

遍历列,调用str.replace

for c in df.columns:
    df[c] = df[c].str.replace('[^\d.]', '')

df = df.astype(float)
df
          0         1  2
0  0.889867  0.895339  0
1  1.263256  1.020766  0
2  1.006649  1.118097  0
3  0.965363  0.862554  0
4  1.038366  0.909145  0

不幸的是,pandas 尚不支持对整个数据帧的字符串访问器操作,因此循环列的替代方法会更慢一些,比如小羊羔的applymap/transform


性能

100 loops, best of 3: 2.04 ms per loop  # applymap 
100 loops, best of 3: 2.69 ms per loop  # transform
1000 loops, best of 3: 1.45 ms per loop  # looped str.replace

大号 (df * 10000)

1 loop, best of 3: 618 ms per loop  # applymap 
1 loop, best of 3: 658 ms per loop  # transform
1 loop, best of 3: 341 ms per loop  # looped str.replace
1 loop, best of 3: 212 ms per loop  # df.replace

【讨论】:

在对就地操作和返回副本的函数进行基准测试时,您可能需要小心。在前一种情况下,第一次替换完成后,剩下的 99 个循环测试实际上并没有做同样的操作,明白了吗? @JohnGalt 让我重新运行 1 个循环。 并且,检查在循环内移动astype(float) 是否会进一步改善它。 @JohnGalt 用一个循环重新运行。此外,在循环中使用 astype 会使情况变得更糟。 @cᴏʟᴅsᴘᴇᴇᴅ 我的回答呢?

以上是关于在熊猫数据框上应用正则表达式函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在熊猫过滤器函数中反转正则表达式

了解熊猫系列提取函数中的正则表达式

根据相同字符的不同位置将正则表达式应用于熊猫列

使用 jquery 验证插件,如何在文本框上添加正则表达式验证?

在熊猫数据框中使用正则表达式替换列值

使用熊猫根据正则表达式分离列数据