롤링 팬더의 속도를 높입니다.
아래에서는 numpy를 사용하여 더 빠른 버전의 롤링 창을 만드는 방법을 살펴봅니다.
다음 스니펫을 고려하십시오.
import pandas as pd
import numpy as np
s = pd.Series(range(10**6))
s.rolling(window=2).mean()
롤링 호출은 크기가 2인 창을 만든 다음 각각의 평균을 계산합니다.
0 NaN
1 0.5
2 1.5
…
999998 999997.5
999999 999998.5
Length: 1000000, dtype: float64
그러나 numpy에서 stride_tricks를 사용하면 값을 더 빠르게 반복하는 함수를 만들 수 있습니다.
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에 이 함수의 버전이 있습니다.
from skimage.util.shape import view_as_windows
)다음과 같이 새로운 롤링_윈도우 함수를 사용할 수 있습니다.
np.mean(rolling_window(s,2), axis=1)
이것은 pandas의 롤링() 메서드를 사용하여 계산한 것과 동일한 데이터를 반환하지만 선행 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)
numpy 버전은 약 두 배 빠릅니다. 다른 크기의 어레이의 경우 성능이 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
Reference
이 문제에 관하여(롤링 팬더의 속도를 높입니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jesloper/speeding-up-rolling-pandas-3860텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)