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”