Рубрики
Без рубрики

Ускорение прокатки панда

Pandas – чрезвычайно полезный пакет для анализа данных в Python и в целом очень исполнен … Теги с Python, Pandas.

Pandas – чрезвычайно полезный пакет для анализа данных в Python и в целом является очень исполнителем. Однако есть некоторые случаи, когда улучшается производительность может иметь значение. Ниже мы смотрим на использование Numpy, чтобы создать более быструю версию Rolling Windows.

Рассмотрим следующий фрагмент:

import pandas as pd
import numpy as np
s = pd.Series(range(10**6))
s.rolling(window=2).mean()

Rolling Call создаст окна размера 2, а затем мы рассчитываем среднее значение для каждого:

0 NaN
1 0.5
2 1.5
 …
999998 999997.5
999999 999998.5
Length: 1000000, dtype: float64

Однако использование Stride_Tricks в Numpy мы можем создать функцию, которая итасирует значения быстрее:

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

( Примечание : Есть версия этой функции в Scikit-Image: от Skimage.util.shape Import View_as_windows )

Мы можем использовать нашу новую функцию Rolling_window следующим образом: NP.MEAN (Rolling_Window (S, 2),)

Это вернет те же данные, поскольку мы рассчитаны с использованием метода Rolling () от Panda, но без ведущего значения NAN.

Измерение производительности

Использование инструмента% TimeIt (удобно встроен в iPython и, следовательно, Jupyter), мы измеряем производительность двух версий:

s = pd.Series(np.random.randint(10, size=10**6))
%timeit s.rolling(window=2).mean()
%timeit np.mean(rolling_window(s, 2), axis=1)

какие выходы:

58.6 ms ± 1.42 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
25.1 ms ± 1.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Облегающая версия примерно в два раза быстрее. Для других размеров массивов производительность будет варьироваться от 2 до 5х быстрее. Давайте снова проверим, но с другим расчетом:

s = pd.Series(np.random.randint(10, size=10**6))
%timeit s.rolling(window=2).sum()
%timeit np.sum(rolling_window(s, 2), axis=1)

какие выходы:

52.5 ms ± 1.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
14.9 ms ± 129 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Вот и все. Мы пожертвоем немного читаемости для значительной скорости вверх.

Примечание Существует множество способов рассчитать средство быстрее, чем версия выше. Если вы действительно смотрите в производительность, см. Ноутбук в этом гисте: Rolling.ipynb.

Оригинал: “https://dev.to/jesloper/speeding-up-rolling-pandas-3860”