Увеличьте скорость чтения панд read_csv для одной строки - PullRequest
4 голосов
/ 21 мая 2019

Я обслуживаю запросы API с довольно жесткими требованиями к задержке, и данные, которые я хочу преобразовать, публикуются по одной строке за раз.Я был озадачен, увидев, что метод pandas read_csv занимает около 2 мс, от которого я не могу отказаться просто для загрузки данных.

Возможны ли дальнейшие улучшения в приведенном ниже коде, такие как аргумент I 'м, что бы ускорить процесс с таким размером данных?

from io import StringIO
import pandas as pd
import numpy as np

example_input = '1969,EH10,consumer'

Метод библиотеки панд с наилучшей оптимизацией, которую я мог найти, был со следующими аргументами:

%%timeit
s = StringIO(example_input)
df = pd.read_csv(s,
                 sep=',',
                 header=None,
                 engine='c',
                 names=['dob', 'postcode', 'contract'],
                 dtype=str,
                 compression=None,
                 na_filter=False,
                 low_memory=False)

, который локальновозвращает 1.75 ms ± 18.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Мне удалось значительно ускорить загрузку с помощью numpy, а затем создать фрейм данных:

%%timeit
s = StringIO(example_input)
a = np.genfromtxt(s, delimiter=',', dtype=str)
df = pd.DataFrame(a.reshape(1, -1),
                  columns=['dob', 'postcode', 'contract'])

, что дает 415 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each), что более приемлемо для моего приложения.(Загрузка только в массив NumPy может быть выполнена за ~ 70,4 мкс без загрузки в информационный кадр, поэтому я могу в итоге работать с этим)

Однако возможно ли еще ускорить пример pd.read_csvи если нет - может кто-нибудь помочь мне понять причины большой дельты здесь?

1 Ответ

3 голосов
/ 21 мая 2019

Обычно мы видим, что pd.read_csv быстрее, чем genfromtxt.Но, очевидно, у него есть время запуска, которое доминирует в этом случае с 1 строкой.

In [95]: example_input = '1969,EH10,consumer'                                
In [96]: np.genfromtxt([example_input], delimiter=',',dtype=str)             
Out[96]: array(['1969', 'EH10', 'consumer'], dtype='<U8')

Но почему бы просто не разбить строку и создать массив из этого?Он более прямой и намного быстрее:

In [97]: np.array(example_input.split(','))                                  
Out[97]: array(['1969', 'EH10', 'consumer'], dtype='<U8')

Создание кадра данных из этого массива занимает больше времени.

In [106]: timeit np.array(example_input.split(','))                          
2.89 µs ± 50.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [107]: timeit pd.DataFrame(np.array(example_input.split(','))[None,:], col
     ...: umns=['dob', 'postcode', 'contract'])                              
406 µs ± 6.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...