2015-06-18 11 views
3

У меня возникают проблемы с производительностью, преобразующие dataframe в csv.Pandas 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 

Почему указание типа кодировки сильно повлияет на производительность этого метода? В моем конкретном случае я предпочел бы использовать значение по умолчанию (None), но поскольку в ядре данных, который мне нужно преобразовать, содержатся некоторые специальные символы (китайский), я не могу использовать кодировку по умолчанию, которая имеет превосходную производительность.

По-видимому, кодировка по умолчанию - «ascii», но при выборе имеет ту же производительность, что и utf8, которая является той, которая мне нужна, чтобы использовать ручку без английского.

Любая идея, как я могу справиться со скоростью и обойти эту проблему?

Я использую pandas 0.16.0 и Python 2.7.9.

EDIT:

Я обновление до панды 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, где, если кодировка не является None, она использовала форматировщик unicode даже для ascii.

Если вам нужен юникод, тем не менее, он чувствует, что он будет немного медленнее с 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

спасибо! Я обновляюсь до pandas 0.16.2, и у меня есть результаты, похожие на ваши (у вас может быть лучший процессор, хотя). Все еще хотелось понять, если это ошибка или что ... –

+1

Я обновил свой ответ ссылкой на исходный код. Это не ошибка, а то, что лучше оптимизировать, если «encoding = 'ascii''. В вашем случае, однако, поскольку вам нужно 'encoding = 'utf8', результаты выглядят разумно. – rth

+1

спасибо! поэтому указание какого-либо типа кодирования будет результатом использования pandas.core.common.UnicodeWriter вместо csv.writer, что приведет к более медленному, даже если вы используете ту же самую среду csv.writer. Результаты намного лучше, чем мой предыдущий опыт! Все еще не так, как использование csv.writer ..., о котором я задаю себе вопрос, стоит отметить, поскольку они делают то же самое, если вы используете «ascii» в качестве кодировки, но не так эффективно. –

Смежные вопросы