2017-02-01 56 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:使用示例數據時序

一些時間比較