在熊猫数据框上应用正则表达式函数
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ᴘᴇᴇᴅ 我的回答呢?以上是关于在熊猫数据框上应用正则表达式函数的主要内容,如果未能解决你的问题,请参考以下文章