2017-02-01 57 views
1

请帮助我了解为什么这个“取代从字典”操作是在Python /熊猫慢:熊猫替换/字典缓慢

# Series has 200 rows and 1 column 
# Dictionary has 11269 key-value pairs 
series.replace(dictionary, inplace=True) 

字典查询应该是O(1)。替换列中的值应该是O(1)。这不是一个矢量化的操作吗?即使它不是矢量化的,迭代200行只有200次迭代,所以它怎么会慢呢?

这里是一个展示SSCCE问题:

import pandas as pd 
import random 

# Initialize dummy data 
dictionary = {} 
orig = [] 
for x in range(11270): 
    dictionary[x] = 'Some string ' + str(x) 
for x in range(200): 
    orig.append(random.randint(1, 11269)) 
series = pd.Series(orig) 

# The actual operation we care about 
print('Starting...') 
series.replace(dictionary, inplace=True) 
print('Done.') 

运行该命令需要我的机器,这是时间长于预期执行< 1000操作1000对超过1秒。

+0

请提供一个可重现的例子,并定义“慢”的含义。当我尝试复制您的设置时,我没有任何性能问题,取而代之的是〜200ms。 – root

+0

使用SSCCE编辑OP。在使用Python时,每操作约1ms真的是预期的性能吗? –

回答

2

它看起来像replace具有一些开销,并明确告诉系列该做什么通过map产生最佳性能:

series = series.map(lambda x: dictionary.get(x,x)) 

如果您确信所有按键都在你的字典,你可以通过不创建lambda来获得非常轻微的性能提升,并直接提供dictionary.get函数。不存在任何键将通过这个方法返回NaN,所以要小心:

series = series.map(dictionary.get) 

还可以提供只字典本身,而是这似乎引入了一些开销:

series = series.map(dictionary) 

%timeit series.map(dictionary.get) 
10000 loops, best of 3: 124 µs per loop 

%timeit series.map(lambda x: dictionary.get(x,x)) 
10000 loops, best of 3: 150 µs per loop 

%timeit series.map(dictionary) 
100 loops, best of 3: 5.45 ms per loop 

%timeit series.replace(dictionary) 
1 loop, best of 3: 1.23 s per loop 
0123:使用示例数据时序

一些时间比较