2015-06-18 86 views
3

我遇到一些將數據幀轉換爲csv的性能問題。熊貓to_csv編碼較慢?

import numpy as np 
import pandas as pd 
from time import time 

t =time();_=pd.DataFrame(np.random.sample((10000,10))).to_csv(encoding=None); print time()-t 
0.159129142761 
t =time();_=pd.DataFrame(np.random.sample((10000,10))).to_csv(encoding='utf8'); print time()-t 
1.16141009331 
t =time();_=pd.DataFrame(np.random.sample((10000,10))).to_csv(encoding='ascii'); print time()-t 
1.13821101189 

爲什麼指定一個編碼類型會大大影響這種方法的性能?在我的特殊情況下,我寧願使用默認值(無),但由於我需要轉換的數據幀包含一些特殊的字符(中文),我不能使用具有卓越性能的默認編碼。

顯然,默認的編碼是「ascii」,但是當選擇與utf8完全一樣的性能時,我需要使用句柄非英文字符。

任何想法如何應對速度和解決這個問題?

我使用的是熊貓0.16.0和Python 2.7.9。

編輯:

我已經升級到大熊貓0.16.2每rth建議的,我也得到更好的時機

import pandas as pd 
import numpy as np 
x = pd.DataFrame(np.random.sample((10000,10))) 
%timeit x.copy().to_csv(encoding='ascii') 
%timeit x.copy().to_csv() 
%timeit x.copy().to_csv(encoding='utf8') 
10 loops, best of 3: 160 ms per loop 
10 loops, best of 3: 73.7 ms per loop 
10 loops, best of 3: 158 ms per loop 

不過它慢半比指定使用的編碼默認編碼。明顯好於以前使用0.16.0版本的情況,但仍然是一個有形的差異。

我仍然渴望瞭解它是否是一個錯誤,我該如何改進它...在我的情況下,它是10分鐘或20分鐘之間的差異!

+0

是的,只有很小的變化,但可重現。 –

回答

3

我猜測轉換爲csv會在本地編碼中輸出一個字符串,然後將其轉換爲請求的編碼,如果兩者相同,則會導致不必要的開銷。看到這個特殊的line in the source code,如果編碼不是無,它甚至使用ASCII碼格式化程序,甚至ASCII。

如果你需要unicode,它會讓感覺它會比python 2.7慢一點,而不是普通的ascii。

在我的情況下,使用Python 2.7.9-r2 64位和pandas 0.16.1-r1,這兩個選項之間的差異僅爲2倍,並不是因子10的因子,而是

In [1]: x = pd.DataFrame(np.random.sample((10000,10))) 
    ...: 
    ...: %timeit x.copy().to_csv(encoding='ascii') 
    ...: %timeit x.copy().to_csv() 
    ...: %timeit x.copy().to_csv(encoding='utf8') 
10 loops, best of 3: 109 ms per loop 
10 loops, best of 3: 56.8 ms per loop 
10 loops, best of 3: 108 ms per loop 

所以這可能潛在encoding='ascii'

+1

謝謝!我已經升級到了熊貓0.16.2,並且我得到了和你相似的結果(儘管你可能有更好的CPU)。仍然渴望瞭解,如果它是一個錯誤或什麼... –

+1

我更新了我的答案與源代碼的鏈接。這不是一個錯誤,如果編碼='ascii'',那麼這可能會更好地優化。然而,在你的情況下,因爲你需要'encoding ='utf8',結果看起來很合理。 – rth

+1

謝謝!所以指定任何類型的編碼都會導致使用pandas.core.common.UnicodeWriter而不是csv.writer,即使使用相同的csv.writer經過,結果也會變得更慢。結果比我以前的經驗更好!仍然不如使用csv.writer ......我不知道是值得注意的事情,因爲如果你使用'ascii'作爲編碼,它們做同樣的事情,但效率不高。 –