Pandas中str.strip的性能表现

12

我原以为第三个选项是去除空格的最快方法?有人能给我一些处理大数据集时应该遵循的通用规则吗?我通常使用.astype(str),但对于我已经知道是对象的列,这显然是不值得的。

%%timeit
fcr['id'] = fcr['id'].astype(str).map(str.strip)
10 loops, best of 3: 47.8 ms per loop

%%timeit
fcr['id'] = fcr['id'].map(str.strip)
10 loops, best of 3: 25.2 ms per loop

%%timeit
fcr['id'] = fcr['id'].str.strip(' ')
10 loops, best of 3: 55.5 ms per loop

1
可能值得在github上问一下为什么会这样,因为这不是我所期望的。 - EdChum
1
最好先进行更多的分析,以确定是什么导致了相对的放缓。一般来说,您最后两个代码片段不等价,因为pandas中的.str方法都:1.) 接受正则表达式或字符串,2.) 处理NaNs而不会出错。或许看看这些方法的开销如何。 - TomAugspurger
1
@TomAugspurger 我在一个简单的30k行df上进行了测试:df = pd.DataFrame({'id':['asds','as asd','asdsa asdasdas']}) df = pd.concat([df]*10000, ignore_index=True),并观察到与OP相同的情况。 - EdChum
1
@TomAugspurger 时间:`In [8]:%timeit df['id'].astype(str).map(str.strip) %timeit df['id'].map(str.strip) %timeit df['id'].str.strip() 10个循环,3次中的最佳结果:每个循环21毫秒 100个循环,3次中的最佳结果:每个循环11.4毫秒 10个循环,3次中的最佳结果:每个循环25.4毫秒` - EdChum
1
正如@TomAugspurger所说,这是可以预料的(map(str.strip)更快),因为str.strip()map(str.strip)相同且更多(检查NaN),因此它总是会慢一些。 - joris
2
我想这里的经验法则是,如果您知道您的数据是简单且非空的,则调用.map(str.strip)会更快,否则对于NaN处理和正则表达式模式,请使用pd.Series.str.strip - EdChum
1个回答

14

首先让我们看一下 .map(str.strip).str.strip() (第二和第三种情况) 之间的区别。
因此,您需要了解 str.strip() 在内部实际上执行了一些 map(str.strip) 操作,但是使用了一个自定义的 map 函数来处理缺失值。
因此,由于 .str.strip() 所做的功能更多,可以预计这种方法始终会比较慢(并且正如您所展示的,在您的情况下要慢2倍)。

使用 .str.strip() 方法具有自动处理 NaN(或其他非字符串值)的优势。假设“id”列包含 NaN 值:

In [4]: df['id'].map(str.strip)
...
TypeError: descriptor 'strip' requires a 'str' object but received a 'float'

In [5]: df['id'].str.strip()
Out[5]:
0                   NaN
1                as asd
2        asdsa asdasdas
              ...
29997              asds
29998            as asd
29999    asdsa asdasdas
Name: id, dtype: object

正如 @EdChum 指出的那样,如果您确定没有 NaN 值并且性能差异很重要,您确实可以使用 map(str.strip)


回到另一个区别fcr['id'].astype(str).map(str.strip)。如果您已经知道系列中的值是字符串,则调用astype(str)是多余的。而正是这个调用解释了差异:

In [74]: %timeit df['id'].astype(str).map(str.strip)
100 loops, best of 3: 10.5 ms per loop

In [75]: %timeit df['id'].astype(str)
100 loops, best of 3: 5.25 ms per loop

In [76]: %timeit df['id'].map(str.strip)
100 loops, best of 3: 5.18 ms per loop
请注意,如果您有非字符串值(NaN、数字值等),使用.str.strip().astype(str).map(str)不会产生相同的结果:
In [11]: s = pd.Series(['  a', 10])

In [12]: s.astype(str).map(str.strip)
Out[12]:
0     a
1    10
dtype: object

In [13]: s.str.strip()
Out[13]:
0      a
1    NaN
dtype: object
正如您所看到的,.str.strip()将非字符串值返回为NaN,而不是将它们转换为字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接