๊ทธ๋ฅ ์ ์ - rolling
๋ฅผ ํ์ฅํ์ฌ R์ rollapply(by=X)
์ ๊ฐ์ ๋จ๊ณ ํฌ๊ธฐ๋ก ๋กค๋ง ์ฐฝ์ ์ง์ํ์ญ์์ค.
Pandas - ๋นํจ์จ์ ์ธ ์๋ฃจ์ (๋ชจ๋ ์ฐฝ์ ๊ธฐ๋ฅ์ ์ ์ฉํ ๋ค์ ๋งค์ด ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ํด ์ฌ๋ผ์ด์ค)
import pandas
ts = pandas.Series(range(0, 40, 2))
ts.rolling(5).apply(max).dropna()[::2]
์ ์:
ts = pandas.Series(range(0, 40, 2))
ts.rolling(window=5, step=2).apply(max).dropna()
R์์ ์๊ฐ์ ์ป์์ต๋๋ค( rollapply ๋ฌธ์ ์ฐธ์กฐ):
require(zoo)
TS <- zoo(seq(0, 40, 2))
rollapply(TS, 5, FUN=max, by=2)
8 12 16 20 24 28 32 36 40
'ํ์ค' ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฒกํฐํ๋๋ฏ๋ก v ๋น ๋ฆ
๋๋ค( ts.rolling(5).max().dropna()[::2]
).
IIUC ์ฌ๊ธฐ์์ ์ ์ฝ์ ์๊ฐ์ ์ผ๋ถ(์: n๋ฒ์งธ ๊ฐ๋ง๋ค)๋ง ํจ์๋ฅผ ์ ์ฉํจ์ผ๋ก์จ ์ป์ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ์ค์ง์ ์ธ ์ฐจ์ด๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๊น?
์ด ์์ ์ ์ํํ ์ ์์ง๋ง ์ด๊ฒ์ด ์ค์ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ณด๊ณ ์ถ์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด '์ ๋ ฅ๊ณผ ๋์ผํ ํฌ๊ธฐ ๋ฐํ' API๋ ์ค๋จ๋ฉ๋๋ค. ๋๋ ์ด๊ฒ์ด ์ค์ ๋ก ๊ตฌํํ๊ธฐ ์ด๋ ต๋ค๊ณ ์๊ฐํ์ง ์์ง๋ง (๊ตฌํ์ ๋ง์ ๋ณ๊ฒฝ ์ฌํญ์ด ํฌํจ๋์ง๋ง). ์ฐ๋ฆฌ๋ ํ๊ณ ์ฐฝ์ ์ฌ์ฉํฉ๋๋ค(IOW, ์ฐฝ์ ๊ณ์ฐํ๊ณ ์งํํ๋ฉด์ ๋ ๋๋ ์ ์ ์ค์ด๊ณ ์ป๋ ์ ์ ์ถ๊ฐํจ). ๋ฐ๋ผ์ ์ฌ์ ํ ๋ชจ๋ ๊ฒ์ ๊ณ์ฐํด์ผํ์ง๋ง ์ถ๋ ฅํ์ง ์์ ๊ฒ์ ๋๋ค.
๋ต์ฅํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
IIUC ์ฌ๊ธฐ์์ ์ ์ฝ์ ์๊ฐ์ ์ผ๋ถ(์: n๋ฒ์งธ ๊ฐ๋ง๋ค)๋ง ํจ์๋ฅผ ์ ์ฉํจ์ผ๋ก์จ ์ป์ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ์ค์ง์ ์ธ ์ฐจ์ด๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๊น?
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ์ผ๋ถ ๋ํ ์๊ณ์ด ๋ฐ์ดํฐ ํ๋ ์(400๊ฐ ์ด, 5-25Hz์์ ๋ฐ์ดํฐ ์๊ฐ)์ ๋ํด ์ง๊ณ ํจ์(์ต๋๊ฐ๋ฟ๋ง ์๋๋ผ)๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค. ๋ํ ๊ณผ๊ฑฐ์ ์ต๋ 20kHz์ ๋ฐ์ดํฐ๋ก ์ ์ฌํ ์์ (์ผ์ ๋ฐ์ดํฐ์ ๋ํ ๊ธฐ๋ฅ ์์ง๋์ด๋ง)์ ์ํํ์ต๋๋ค. 30์ด ์ฐฝ์ 5์ด ๋จ๊ณ๋ก ์คํํ๋ฉด ์ฒ๋ฆฌ๋์ ํฌ๊ฒ ์ ์ฝํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 25Hz์์ 5์ด ๋จ๊ณ๋ก ์คํํ๋ฉด ์์ ์ 1/125์ ๋ถ๊ณผํ๋ฏ๋ก 1๋ถ ๋๋ 2์๊ฐ ๋ง์ ์คํํ๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
๋ถ๋ช ํ numpy๋ก ๋์๊ฐ ์ ์์ง๋ง ์ด๋ฅผ ์ํํ๊ธฐ ์ํ ๋ ๋์ ์์ค์ API๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค๋ ์ ์ฉํ๋ค๊ณ ์๊ฐํ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ์ ์ํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ ๋ฅผ ์ํ ๊ธฐ๋ฅ์ ๊ตฌ์ถํ ๊ฒ์ด๋ผ๊ณ ๋ ์๊ฐํ์ง ์์ต๋๋ค!
๋จผ์ ๋ ๋์ ์ฃผํ์ ๊ฐ๊ฒฉ์ผ๋ก ๋ฆฌ์ํ๋ง์ ์๋ํ ๋ค์ ๋กค๋ง์ ์๋ํ ์ ์์ต๋๋ค.
๋ญ๊ฐ
df = df.resample('30์ด')
df.rolling(..).max() (๋๋ ์ด๋ค ๊ธฐ๋ฅ์ด๋ )
@jreback๋ , ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์ด๊ฒ์ ๋ด ๋ฐ์ดํฐ์์ max
๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ ์๋ํฉ๋๋ค(resample์๋ ์ถ์ ๊ธฐ๋ฅ์ด ํ์ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ mean
, ๋ง์ต๋๊น?):
df.resample('1s').max().rolling(30).max()
๊ทธ๋ฌ๋ 30์ด์ ๋ฐ์ดํฐ์ ๋ํด ์ถ์ ๊ธฐ๋ฅ์ ์คํํ ๋ค์ 1์ด ์์ผ๋ก ์ด๋ํ๊ณ ๋ค์ 30์ด์ ๋ฐ์ดํฐ์ ๋ํด ์คํํ๊ณ ์ถ์ต๋๋ค. ์์ ๋ฐฉ๋ฒ์ 1์ด์ ๋ฐ์ดํฐ์ ํจ์๋ฅผ ์ ์ฉํ ๋ค์ ๋ค๋ฅธ ์ฒซ ๋ฒ์งธ ํจ์์ 30๊ฐ ๊ฒฐ๊ณผ์ ๋ํ ํจ์์ ๋๋ค.
๋ค์์ ๊ฐ๋จํ ์์ ๋๋ค. ํผํฌ ๋ ํผํฌ ๊ณ์ฐ์ ์คํํ๋ฉด ๋ ๋ฒ ์คํ๋์ง ์์ต๋๋ค(๋ถ๋ช ํ).
# 10 minutes of data at 5Hz
n = 5 * 60 * 10
rng = pandas.date_range('1/1/2017', periods=n, freq='200ms')
np.random.seed(0)
d = np.cumsum(np.random.randn(n), axis=0)
s = pandas.Series(d, index=rng)
# Peak to peak
def p2p(d):
return d.max() - d.min()
def p2p_arr(d):
return d.max(axis=1) - d.min(axis=1)
def rolling_with_step(s, window, step, func):
# See https://ga7g08.github.io/2015/01/30/Applying-python-functions-in-moving-windows/
vert_idx_list = np.arange(0, s.size - window, step)
hori_idx_list = np.arange(window)
A, B = np.meshgrid(hori_idx_list, vert_idx_list)
idx_array = A + B
x_array = s.values[idx_array]
idx = s.index[vert_idx_list + int(window/2.)]
d = func(x_array)
return pandas.Series(d, index=idx)
# Plot data
ax = s.plot(figsize=(12, 8), legend=True, label='Data')
# Plot resample then rolling (obviously does not work)
s.resample('1s').apply(p2p).rolling(window=30, center=True).apply(p2p).plot(ax=ax, label='1s p2p, roll 30 p2p', legend=True)
# Plot rolling window with step
rolling_with_step(s, window=30 * 5, step=5, func=p2p_arr).plot(ax=ax, label='Roll 30, step 1s', legend=True)
@alexlouden ๊ทํ์ ์๋ ์ค๋ช ์์ ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์๊ฐํฉ๋๋ค.
df.resample('5s').max().rolling('30s').mean()
(๋๋ ๋ชจ๋ ๊ฐ์)๊ฐ ์ํ๋ ๊ฒ๊ณผ ๋ ์ผ์นํฉ๋๋ค.
IOW, 5s bin์ ์๋ ๋ชจ๋ ๊ฒ์ ๊ฐ์ ธ ์์ ๋จ์ผ ์ง์ ์ผ๋ก ์ค์ธ ๋ค์ ํด๋น bin์ ๋กค์ค๋ฒํ์ญ์์ค. ์ด ์ผ๋ฐ์ ์ธ ์์ด๋์ด๋ ์งง์ ์๊ฐ ๊ท๋ชจ๋ก ์์ฝํ ์ ์๋ ๋ง์ ๋ฐ์ดํฐ๊ฐ ์์ง๋ง ์ค์ ๋ก๋ ๋ ๋์ ์์ค์์ ์ด๋ฅผ ๋กค๋งํ๊ธฐ๋ฅผ ์ํ๋ค๋ ๊ฒ์ ๋๋ค.
@jreback๋ , ์ค์ ๋ก 5์ด๋ง๋ค 30์ด ๋ถ๋์ ๋ฐ์ดํฐ์ ๋ํด ํจ์๋ฅผ ์คํํ๊ณ ์ถ์ต๋๋ค. ์ด์ ์์ ์์ rolling_with_step ํจ์๋ฅผ ์ฐธ์กฐํ์ญ์์ค. ์ต๋/ํ๊ท ์ ์ถ๊ฐ ๋จ๊ณ๋ ๋ด ์ฌ์ฉ ์ฌ๋ก์์ ์๋ํ์ง ์์ต๋๋ค.
@jreback , ์์ง ์ด ํ ๋ก ์์ ๋์ค์ง ์์ ๋จ๊ณ ๊ธฐ๋ฅ์ด ์ค์ ๋ก ํ์ํฉ๋๋ค. @alexlouden ์ด ์ค๋ช ํ ๋ชจ๋ ๊ฒ์ ๋ ๋ฒ์งธ๋ก ํ๊ณ ์์ง๋ง ๋ ๋ง์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ต๋๋ค.
์ฝ 3~10๋ฐ๋ฆฌ์ด๋ก ์ํ๋ง๋ ์ ๋ ฅ ๋ฐ์ดํฐ๋ก ์๊ณ์ด ๋ถ์์ ์ํํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ฃผํ์ ์์ญ ๊ธฐ๋ฅ์ ๊ด์ฌ์ด ์์ต๋๋ค. ๊ทธ๊ฒ๋ค์ ๊ตฌ์ฑํ๋ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ Nyquist ์ฃผํ์๋ฅผ ์ฐพ๋ ๊ฒ์ ๋๋ค. ๋๋ฉ์ธ ์ง์์ผ๋ก 10Hz(100ms๋ง๋ค ํ ๋ฒ)์์ ์๊ณ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ์ฆ, ๊ธฐ๋ฅ์ด ์ ๋ ฅ ์ ํธ๋ฅผ ์ ์บก์ฒํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ์ ์ฃผํ์๊ฐ ์ต์ 20Hz(50ms๋ง๋ค ํ ๋ฒ)์ฌ์ผ ํฉ๋๋ค. ๊ทธ๋ณด๋ค ๋ฎ์ ์ฃผํ์๋ก ๋ฆฌ์ํ๋งํ ์ ์์ต๋๋ค. ๊ถ๊ทน์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์ํํ๋ ๊ณ์ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
df.resample('50ms').mean().rolling(window=32).aggregate(power_spectrum_coeff)
์ฌ๊ธฐ์์ 8์ ๋ฐฐ์๋ก ์ฐฝ ํฌ๊ธฐ๋ฅผ ์ ํํ์ผ๋ฉฐ 32๋ฅผ ์ ํํ๋ฉด ์ฐฝ ํฌ๊ธฐ๊ฐ 1.6์ด๊ฐ ๋ฉ๋๋ค. ์ง๊ณ ํจ์๋ ์ฒซ ๋ฒ์งธ ํ๊ท ์ฑ๋ถ ์์ด ๋จ๋ฉด ์ฃผํ์ ๋๋ฉ์ธ ๊ณ์๋ฅผ ๋ฐํํฉ๋๋ค(fft ํจ์๋ ๋์นญ์ด๊ณ 0๋ฒ์งธ ์์์ ํ๊ท ๊ฐ์ด ์์). ๋ค์์ ์ํ ์ง๊ณ ํจ์์ ๋๋ค.
def power_spectrum_coeff():
def power_spectrum_coeff_(x):
return np.fft.fft(x)[1 : int(len(x) / 2 + 1)]
power_spectrum_coeff_.__name__ = 'power_spectrum_coeff'
return power_spectrum_coeff_
์ด์ , ์๋ฅผ ๋ค์ด ๋งค 0.4์ด ๋๋ ๋งค 0.8์ด์ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ์์ ์ด๊ฒ์ ๋ฐ๋ณตํ๊ณ ์ถ์ต๋๋ค. ๊ณ์ฐ์ ๋ญ๋นํ๊ณ ๋์ 50ms๋ง๋ค FFT๋ฅผ ๊ณ์ฐํ ๋ค์ ๋์ค์ ์ฌ๋ผ์ด์ฑํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๋ํ 400ms๊น์ง ๋ฆฌ์ํ๋งํ๋ ๊ฒ์ ์ต์ ์ด ์๋๋๋ค. 400ms๋ Nyquist ์ฃผํ์๋ณด๋ค ํจ์ฌ ๋ฎ์ 2.5Hz์ ๋ถ๊ณผํ๊ณ ๊ทธ๋ ๊ฒ ํ๋ฉด ๊ธฐ๋ฅ์์ ๋ชจ๋ ์ ๋ณด๊ฐ ์์ค๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๊ฒ์ ๋ง์ ์๊ณ์ด ๊ด๋ จ ๊ณผํ ์คํ์ ์์ฉ๋๋ ์ฃผํ์ ์์ญ ๊ธฐ๋ฅ์ด์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ์ค ํธ์ฐจ์ ๊ฐ์ ๋ ๊ฐ๋จํ ์๊ฐ ์์ญ ์ง๊ณ ํจ์๋ ๋ฆฌ์ํ๋ง์ผ๋ก ํจ๊ณผ์ ์ผ๋ก ์ง์ํ ์ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ด ์ค์ ๋ก ๊ตฌํํ๊ธฐ ์ด๋ ต๋ค๊ณ ์๊ฐํ์ง ์์ง๋ง (๊ตฌํ์ ๋ง์ ๋ณ๊ฒฝ ์ฌํญ์ด ํฌํจ๋์ง๋ง). ์ฐ๋ฆฌ๋ ํ๊ณ ์ฐฝ์ ์ฌ์ฉํฉ๋๋ค(IOW, ์ฐฝ์ ๊ณ์ฐํ๊ณ ์งํํ๋ฉด์ ๋ ๋๋ ํฌ์ธํธ๋ฅผ ์ญ์ ํ๊ณ ์ป๋ ํฌ์ธํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค). ๋ฐ๋ผ์ ์ฌ์ ํ ๋ชจ๋ ๊ฒ์ ๊ณ์ฐํด์ผํ์ง๋ง ์ถ๋ ฅํ์ง ์์ ๊ฒ์ ๋๋ค.
'step' ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ๊ณ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๊ณ์ฐ์ ์ค์ผ ์ ์๋ ๊ฒ์ Pandas์ ๋ฏธ๋ ๋ชฉํ์ฌ์ผ ํฉ๋๋ค. ๋จ๊ณ ๋งค๊ฐ๋ณ์๊ฐ ๋ ์ ์ ์์ ํฌ์ธํธ๋ง ๋ฐํํ๋ ๊ฒฝ์ฐ ์ถ๋ ฅ์ ์ด๋ป๊ฒ๋ ์ฌ๋ผ์ด์คํ ์ ์์ผ๋ฏ๋ก ์ํํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ์๋ง๋ ์ด ์์ ๊ณผ ๊ด๋ จ๋ ์์ ์ ๊ณ ๋ คํ ๋ ์ด๋ฌํ ์๊ตฌ ์ฌํญ์ด ์๋ ๋ชจ๋ ํ๋ก์ ํธ์์ Numpy๋ฅผ ์ฌ์ฉํ๋๋ก ๊ถ์ฅํ ์ ์์ต๋๋ค.
@Murmuria ์ด๋ฅผ ์ํํ๊ธฐ ์ํด ํ ๋ฆฌํ์คํธ๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค. ์ฌ์ค ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์ต๋๋ค.
rolling()
์์ step
๋งค๊ฐ๋ณ์์ ๋ํ ์์ฒญ์ ๋ ๋ฒ์งธ๋ก ํ๋ ๋์ rolling()
์์ base
๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์์ ์ง์ ํ๊ณ ์ถ์ต๋๋ค resample()
, ๋จ๊ณ ํฌ๊ธฐ๊ฐ ์ฐฝ ํฌ๊ธฐ์ ์ ์ ๋ถ์์ธ ๊ฒฝ์ฐ . @alexlouden ์ ์ ์ฌ์ฉ:
pandas.concat([
s.resample('30s', label='left', loffset=pandas.Timedelta(15, unit='s'), base=i).agg(p2p)
for i in range(30)
]).sort_index().plot(ax=ax, label='Solution with resample()', legend=True, style='k:')
์ฐ๋ฆฌ๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ต๋๋ค(์ ์ด ์์ชฝ์์ 30์ด ์ฐ์ฅ๋จ).
์ด๋ ์ง๊ณ ์ ํ์ ๋ฐ๋ผ ์ฌ์ ํ ๋ค์ ๋ญ๋น์
๋๋ค. @alexlouden ์ ์์์์ ๊ฐ์ ํผํฌ ๋ ํผํฌ ๊ณ์ฐ์ ํน์ ๊ฒฝ์ฐ์ ๋ํด p2p_arr()
๋ ๊ณ์ด์ 2์ฐจ์ ํ๋ ฌ๋ก ์ฌ์ ๋ ฌํ ๋ค์ max()
๋ํ ๋จ์ผ ํธ์ถ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฑฐ์ 200๋ฐฐ ๋น ๋ฆ
๋๋ค. min()
.
๋กค๋ง์ ๋จ๊ณ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ์ง/์๊ฐ ์ธ๋ฑ์ค ์์ด ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ์ด๋ฏธ ์์ ์ค์ธ ์ฌ๋์ด ์์ต๋๊น?
์์ @alexlouden ์ ๋ค์๊ณผ ๊ฐ์ด ๋งํ์ต๋๋ค.
๋ถ๋ช ํ numpy๋ก ๋์๊ฐ ์ ์์ง๋ง ์ด๋ฅผ ์ํํ๊ธฐ ์ํ ๋ ๋์ ์์ค์ API๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
@alexlouden ์ด๋ ์๋ ์ฌ๋์ด numpy๋ก ์ด ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํต์ฐฐ๋ ฅ์ ๊ณต์ ํ ์ ์์ต๋๊น? ์ง๊ธ๊น์ง์ ์ฐ๊ตฌ์์ numpy์์๋ ์ด๊ฒ์ ์ํํ๋ ๊ฒ์ด ์ฌ์ํ ์ผ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฌ์ค, ์ฌ๊ธฐ์ ๋ํ ๋ฏธํด๊ฒฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. https://github.com/numpy/numpy/issues/7753
๊ฐ์ฌ ํด์
์๋
ํ์ธ์ @tsando - ์์์ ์ฌ์ฉํ rolling_with_step
๊ธฐ๋ฅ์ด ์๋ํ์ง ์์ต๋๊น?
@alexlouden ๊ฐ์ฌํฉ๋๋ค. ๋ฐฉ๊ธ ๊ทธ ๊ธฐ๋ฅ์ ํ์ธํ๋๋ฐ ์ฌ์ ํ ํฌ๋์ ์์กดํ๋ ๊ฒ ๊ฐ์ต๋๋ค(์๋ฆฌ์ฆ๋ฅผ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉํ๊ณ ์๋ฆฌ์ฆ ์ธ๋ฑ์ค๋ ์ฌ์ฉ). ๋๋ ์ด๊ฒ์ ๋ํด ์์ ํ numpy ์ ๊ทผ ๋ฐฉ์์ด ์๋์ง ๊ถ๊ธํฉ๋๋ค. ๋ด๊ฐ ์ธ๊ธํ ์ค๋ ๋์์ https://github.com/numpy/numpy/issues/7753 ๊ทธ๋ค์ numpy strides๋ฅผ ์ฌ์ฉํ๋ ํจ์๋ฅผ ์ ์ํ์ง๋ง ์ฐฝ ๋ฐ ๋จ๊ณ ์ ๋ ฅ์ ์ดํดํ๊ณ ๋ณํํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค.
@tsando ์ฌ๊ธฐ ๋ด๊ฐ ์์ ๋งํฌํ ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ ํ๊ณ ์ฌ์ดํธ ๋ฅผ ๋ค์
์์ ๋ด ๊ธฐ๋ฅ์ Pandas์ ํจ๊ป ์๋ํ๋๋ก ๊ทธ์ ๋ง์ง๋ง ์์ ๋ฅผ ๋ณํํ๋ ๊ฒ์ ๋๋ค. numpy๋ฅผ ์ง์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค. https://gist.github.com/alexlouden/e42f1d96982f7f005e62ebb737dcd987
๋์์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
@alexlouden ๊ฐ์ฌํฉ๋๋ค! ๋ฐฉ๊ธ (13, 1313)
๋ชจ์์ ๋ฐฐ์ด์์ ์๋ํ์ง๋ง ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
"์ด๊ฒ์ ํ ์ ์์ง๋ง ์ด๊ฒ์ด ์ค์ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ๋ณด๊ณ ์ถ์ต๋๋ค."
ํฌ๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ ํ๋ก์ ํธ๊ฐ ๋ฌด์์ด๋ ๊ฐ์ ์ด ๊ธฐ๋ฅ์ ๊ฑฐ์ ํญ์ ๋์ณค์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๊ฐ๋์ฉ๋ง ์ ์ฉ์ ๊ณ์ฐํด์ผ ํ ๋๋ง๋ค ์ ์ฉํ์ง๋ง ์ฌ์ ํ ๊ฐ ์ฐฝ ๋ด์์ ์ข์ ํด์๋๊ฐ ํ์ํฉ๋๋ค.
์ ๋ ์ด ๊ธฐ๋ฅ์ ๋์ํ๊ณ ์ง์งํฉ๋๋ค
์๊ณ์ด์ ๋ค๋ฃฐ ๋ ๊ฑฐ์ ๋งค๋ฒ ํ์๋ก ํ๋ ์ด ๊ธฐ๋ฅ์ ์๊ฐํ์ ๋ถ์ ๋ชจ๋๋ฅผ ์ํ ์๊ณ์ด ๊ธฐ๋ฅ์ ์์ฑํ๋ ๋ฐ ํจ์ฌ ๋ ๋์ ์ ์ด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ด ์์ด๋์ด๋ฅผ ์ ๊ทน ์ง์ํ์ญ์์ค!
์ด ๊ธฐ๋ฅ์ ๋์ํ๊ณ ์ง์ํฉ๋๋ค.
์ด๊ฒ์ ์ข์ ์ฐฝ ํด์๋๋ฅผ ์ ์งํ๋ฉด์ ๊ณ์ฐ ์๊ฐ์ ์ค์ด๋ ๋ฐ ๋งค์ฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
ํน์ ๋์์ ๋ฐ๋ผ ์ถ๊ฐ๋ก ์กฐ์ ํ ์ ์๋ ์๋ฃจ์ ์ฝ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
def average_smoothing(signal, kernel_size, stride):
sample = []
start = 0
end = kernel_size
while end <= len(signal):
start = start + stride
end = end + stride
sample.append(np.mean(signal[start:end]))
return np.array(sample)
์ด ๊ธฐ๋ฅ์ ๋์ํ๊ณ ์ง์ํฉ๋๋ค. ์ง๊ธ ์คํฑ๋ชจ์ ์ผ๋ก ๋ณด๊ณ ์์ต๋๋ค.
TB์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ๊ณ์ฐ ๋ฐ ๋ค์ด์ํ๋ง์ ์ต์ ์ด ์๋๋๋ค.
์ ๊ฐ ํ๋ ์ผ์๋ ๋ง์ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ๋ก์ปฌ ์กฐ๊ฑด์ ์ดํดํ๊ธฐ ์ํด ๊ฒน์น์ง ์๋ ์ฐฝ์ ๋ํ ๋ค์ํ ํต๊ณ๊ฐ ํ์ํ TB์ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค. ํ์ฌ "์์ "์ ๋ฐ์ดํฐ ํ๋ ์๊ณผ ์์จ์ ํต๊ณ๋ฅผ ์ฌ๋ผ์ด์คํ๋ ์์ฑ๊ธฐ๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. ์ด ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ๋งค์ฐ ์ ์ฉํ ๊ฒ์ ๋๋ค.
์ด ๊ธฐ๋ฅ์ ์๊ณ์ด์ด ๊ด๋ จ๋ ๋ ์ค์ ๋ก ์์ด์ผ ํฉ๋๋ค!
๋์ํฉ๋๋ค. ํ์คํ ์ด ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์ด์ผ ํฉ๋๋ค. ์ฃผ๊ฐ ๊ฐ์ ์คํ ์ฐฝ ์๊ด ๊ด๊ณ๋ฅผ ์ํํ๋ ค๊ณ ํ๊ณ ์ด์ ๋ํ ๊ณ ์ ํ ๊ธฐ๋ฅ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
๊ทธ๋ฐ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ด ์์ง ์๋ค๋ ๊ฒ์ด ๋ฏฟ๊ธฐ์ง ์์ต๋๋ค!
์ด ๋ฌธ์ ๋ ์ธ์ ํด๊ฒฐ๋ฉ๋๊น?
๊ฐ์ฌ ํด์
'์ถ๊ฐ ํ ๋ก '์ ๊ธฐ์ฌํ๋ ค๋ฉด:
๋ด ์ฌ์ฉ ์ฌ๋ก๋ 1์ด์ ํด์๋๋ก ํ ๋ฌ์ ๋ฐ์ดํฐ์ ๋ํด ์๊ฐ๋น ํ๋์ ์ต์/์ต๋/์ค์๊ฐ์ ๊ณ์ฐํ๋ ๊ฒ์
๋๋ค. ๊ทธ๊ฒ์ ์๋์ง ์ฌ์ฉ ๋ฐ์ดํฐ์ด๋ฉฐ ๋ฆฌ์ํ๋ง์ผ๋ก ์์ 1-2 ์ด์ ํผํฌ๊ฐ ์์ต๋๋ค. ๊ทธ ์ธ์๋ ์๋ฅผ ๋ค์ด 5์ด/1๋ถ์ผ๋ก ๋ฆฌ์ํ๋งํด๋ ํ๋ฃจ์ ํ์ํ 24๊ฐ์ ์ฐฝ์ ๊ณ์ฐํ ์ ์๋ ๊ฒ๋ณด๋ค ๋ฒ๋ ค์ผ ํ๋ ํ๋ฃจ์ 4k/1k ์ฐฝ์ ๊ณ์ฐํด์ผ ํ๋ค๋ ์ฌ์ค์ด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค. .
groupby aso๋ฅผ ์ฌ์ฉํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ง๋ง ๋กค๋ง ๊ตฌํ(์ ๋ ฌ์ด ํฌํจ๋ 250๋ง ์๊ฐ ์ฐฝ์ ๊ฒฝ์ฐ 2์ด)๋งํผ ์ง๊ด์ ์ด์ง๋ ๋น ๋ฅด์ง๋ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋๋๋ก ๋น ๋ฅด๊ณ ์ ์ฉํ์ง๋ง ๊ทธ ํ์ ์ต๋ํ ํ์ฉํ๋ ค๋ฉด ๋ณดํญ ์ฃผ์ฅ์ด ํ์ํฉ๋๋ค.
๋ฌธ์ ๋ฅผ ์ดํด๋ณด์์ต๋๋ค. ์ด๊ฒ์ ์๋์ ์ผ๋ก ์ฌ์ํ์ง๋ง ์ฝ๋๊ฐ ๊ตฌํ๋๋ ๋ฐฉ์์ผ๋ก ๋ณผ ๋ ๋ชจ๋ ๋กค๋ง ๋ฃจํด์ ์๋์ผ๋ก ํธ์งํ๋ ๋ฐ ๋๊ตฐ๊ฐ๊ฐ ํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ค ์ค ๋๊ตฌ๋ ์ธ๋ฑ์ ํด๋์ค์ ์ํด ์ฃผ์ด์ง ์ฐฝ ๊ฒฝ๊ณ๋ฅผ ์กด์คํ์ง ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด ์์ฒญ๊ณผ #11704 ๋ชจ๋ ๋งค์ฐ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค. ์ด์จ๋ , ๋๋ ๋ฌผ๊ฑด์ ์ ๋ฆฌํ๋ ๋ฐ ์๊ฐ์ ๋ณด๋ด๊ณ ์ถ์ ์ฌ๋์๊ฒ ๊ด๋ฆฌํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ๋ฐ์ฏค ๊ตฌ์ด PR์ ์์ํ์ต๋๋ค.
๋ฌ๋ฆฌ๊ธฐ:
import numpy as np
import pandas as pd
data = pd.Series(
np.arange(100),
index=pd.date_range('2020/05/12 12:00:00', '2020/05/12 12:00:10', periods=100))
print('1s rolling window every 2s')
print(data.rolling('1s', step='2s').apply(np.mean))
data.sort_index(ascending=False, inplace=True)
print('1s rolling window every 500ms (and reversed)')
print(data.rolling('1s', step='500ms').apply(np.mean))
์์ต๋ฅ
1s rolling window every 2s
2020-05-12 12:00:00.000000000 4.5
2020-05-12 12:00:02.020202020 24.5
2020-05-12 12:00:04.040404040 44.5
2020-05-12 12:00:06.060606060 64.5
2020-05-12 12:00:08.080808080 84.5
dtype: float64
1s rolling window every 500ms (and reversed)
2020-05-12 12:00:10.000000000 94.5
2020-05-12 12:00:09.494949494 89.5
2020-05-12 12:00:08.989898989 84.5
2020-05-12 12:00:08.484848484 79.5
2020-05-12 12:00:07.979797979 74.5
2020-05-12 12:00:07.474747474 69.5
2020-05-12 12:00:06.969696969 64.5
2020-05-12 12:00:06.464646464 59.5
2020-05-12 12:00:05.959595959 54.5
2020-05-12 12:00:05.454545454 49.5
2020-05-12 12:00:04.949494949 44.5
2020-05-12 12:00:04.444444444 39.5
2020-05-12 12:00:03.939393939 34.5
2020-05-12 12:00:03.434343434 29.5
2020-05-12 12:00:02.929292929 24.5
2020-05-12 12:00:02.424242424 19.5
2020-05-12 12:00:01.919191919 14.5
2020-05-12 12:00:01.414141414 9.5
2020-05-12 12:00:00.909090909 4.5
dtype: float64
๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ PR(๋๋ ์ฌ๊ธฐ: https://github.com/anthonytw/pandas/tree/rolling-window-step)์ ์ฐธ์กฐํ์ญ์์ค.
๋๋ด๋ ๋ฐ ๋ ๋ง์ ์๊ฐ์ ํ ์ ํ๊ณ ์ถ์์ง๋ง ๋ถํํ๋ ๋ชจ๋ ๋กค๋ง ๊ธฐ๋ฅ์ ์ฌ์์ ํ๋ ํ๋ ์์ ์ ์ฒ๋ฆฌํ ์๊ฐ์ด ๋จ์ ์์ง ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ ํ๋ ๋ชจ๋ ์ฌ๋์๊ฒ ์ธ๋ฑ์ ํด๋์ค์ ์ํด ์์ฑ๋ ์ฐฝ ๊ฒฝ๊ณ๋ฅผ ์ ์ฉํ๊ณ ๋กค๋ง_*_๊ณ ์ /๋ณ์ ๊ธฐ๋ฅ์ ํตํฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์์ ๋ฐ ๋ ๊ฒฝ๊ณ๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๊ท ์ผ ์ํ๋ง๋ ๋ฐ์ดํฐ๋ก ํน๋ณํ ์์ ์ ์ํํ๋ ํจ์๊ฐ ์๋ ๊ฒฝ์ฐ(์ด ๊ฒฝ์ฐ ํน์ ํจ์๊ฐ ๋์์ค๋ฅผ ๋ ์ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก ํ๋๊ทธ ๋๋ ๋ฌด์ธ๊ฐ๋ฅผ ์ค์ ).
get_window_bounds()
์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ ์ฌ์ฉ์ ์ง์ ์ฐฝ์์๋ ์๋ํฉ๋๊น?
์๋ ํ์ธ์, ๋ ๋ฒ์งธ ์ ์๋ ๋ถํ๋๋ฆฝ๋๋ค. ์ด๊ฒ์ ์ ๋ง ์ ์ฉํ ๊ธฐ๋ฅ์ด ๋ ๊ฒ์ ๋๋ค.
'ํ์ค' ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฒกํฐํ๋๋ฏ๋ก v ๋น ๋ฆ ๋๋ค(
ts.rolling(5).max().dropna()[::2]
).IIUC ์ฌ๊ธฐ์์ ์ ์ฝ์ ์๊ฐ์ ์ผ๋ถ(์: n๋ฒ์งธ ๊ฐ๋ง๋ค)๋ง ํจ์๋ฅผ ์ ์ฉํจ์ผ๋ก์จ ์ป์ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ์ค์ง์ ์ธ ์ฐจ์ด๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๊น?
์ฌ๊ธฐ์ ๊ทธ๋ฌํ ์๊ฐ ์์ต๋๋ค. https://stackoverflow.com/questions/63729190/pandas-resample-daily-data-to-annual-data-with-overlap-and-offset
N ๋ฒ์งธ๋ง๋ค 365 ๋ฒ์งธ๊ฐ๋ฉ๋๋ค. ์ฐฝ ํฌ๊ธฐ๋ ํ๋ก๊ทธ๋จ ์๋ช ๋์ ๊ฐ๋ณ์ ์ด๋ฉฐ ๋จ๊ณ๋ ์ฐฝ ํฌ๊ธฐ์ ์ ์ ๋น์จ์ด ๋๋๋ก ๋ณด์ฅ๋์ง ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ง๊ธ๊น์ง ์ด ๋ฌธ์ ์ ๋ํด ์ฐพ์ ๋ชจ๋ ์๋ฃจ์ ์์ ๋ถ๊ฐ๋ฅํ "๋ณด๊ณ ์๋ ์ฐ๋์ ์ผ ์"๋งํผ ์ค์ ๋ ์ฐฝ ํฌ๊ธฐ๊ฐ ํ์ํฉ๋๋ค.
๋๋ ๋ํ ๋ค์๊ณผ ๊ฐ์ ๋งฅ๋ฝ์์ ๋น์ทํ ํ์๊ฐ ์์ต๋๋ค(์ค์ ์ ์ด๊ณ ์ ๋ฌธ์ ์ธ ํ์์ ๋ฐ๋ผ ์กฐ์ ๋จ).
๋ด๊ฐ ์ดํดํ๋ ํ dataframe.rolling() API๋ฅผ ์ฌ์ฉํ๋ฉด 365์ผ ๊ธฐ๊ฐ์ ์ง์ ํ ์ ์์ง๋ง ๋ค์ ํ๊ท ์ ๊ณ์ฐํ๊ธฐ ์ํด 30์ผ์ ๊ฐ(์ผ์ ํ์ง ์์ ํ ์)์ ๊ฑด๋๋ธ ํ์๋ ์์ต๋๋ค. 365์ผ ๊ฐ ์ ํ.
๋ถ๋ช ํ, ๋ด๊ฐ ๊ธฐ๋ํ๋ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ ํ๋ ์์ ์ด๊ธฐ '๊ฐ ์ด๋ฒคํธ' ๋ฐ์ดํฐ ํ๋ ์๋ณด๋ค (ํจ์ฌ) ์ ์ ์์ ํ์ ๊ฐ์ง ๊ฒ์ ๋๋ค.
๊ฐ๋จํ ์๋ฅผ ํตํด ์ด ์์ฒญ์ ๋ํด ๋ ๋ช ํํ๊ฒ ์ดํดํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
์ด ์๋ฆฌ์ฆ๊ฐ ์๋ ๊ฒฝ์ฐ:
In [1]: s = pd.Series(range(5))
In [2]: s
Out[2]:
0 0
1 1
2 2
3 3
4 4
dtype: int64
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋์ ์ฐฝ ํฌ๊ธฐ๊ฐ 2
์์ ์คํ
ํฌ๊ธฐ 1
. 0
์ธ๋ฑ์ค์ ์๋ ์ด ์ฒซ ๋ฒ์งธ ์ฐฝ์ ํ๊ฐํ๊ณ , 1
์ธ๋ฑ์ค์ ์๋ ์ฐฝ์ ๊ฑด๋๋ฐ๊ณ , 2
์ธ๋ฑ์ค์ ์๋ ์ฐฝ์ ํ๊ฐํฉ๋๊น?
In [3]: s.rolling(2, step=1, min_periods=0).max()
Out[3]:
0 0.0
1 NaN # step over this observation
2 2.0
3 NaN # step over this observation
4 4.0
dtype: float64
๋ง์ฐฌ๊ฐ์ง๋ก ์ด ์๊ฐ ๊ธฐ๋ฐ ์๋ฆฌ์ฆ๊ฐ ์๋ ๊ฒฝ์ฐ
In [1]: s = pd.Series(range(5), index=pd.DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06', '2020-01-09']))
In [2]: s
Out[2]:
2020-01-01 0
2020-01-02 1
2020-01-03 2
2020-01-06 3
2020-01-09 4
dtype: int64
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋์ ์ฐฝ ํฌ๊ธฐ๊ฐ '3D'
์์ ์คํ
ํฌ๊ธฐ '3D'
. ์ด๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋ ๊น์?
In [3]: s.rolling('3D', step='3D', min_periods=0).max()
Out[3]:
2020-01-01 0.0 # evaluate this window
2020-01-02 NaN # step over this observation (2020-01-01 + 3 days > 2020-01-02)
2020-01-03 NaN # step over this observation (2020-01-01 + 3 days > 2020-01-03)
2020-01-06 3.0 # evaluate this window ("snap back" to this observation)
2020-01-09 4.0 # evaluate this window (2020-01-06 + 3 days = 2020-01-09)
dtype: float64
@mroeschke wrt ์ฒซ ๋ฒ์งธ ์([3]), ๊ฒฐ๊ณผ๋ ๋ด๊ฐ ์์ํ ๊ฒ๊ณผ
์ธ๋ฑ์ฑ์ ๊ฒฝ์ฐ ๋จ๊ณ ํฌ๊ธฐ = 1์ด ํ์ฌ ๋์์ ๋๋ค. ์ฆ, ์ฐฝ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ด์ฌ ๊ธฐ๋ฅ์ ๊ณ์ฐํ๊ณ ์ฐฝ์ 1๋งํผ ์ด๋ํ ๋ค์ ๋ฐ๋ณตํฉ๋๋ค. ์ด ์์์๋ ์ฐฝ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ด์ฌ ๊ธฐ๋ฅ์ ๊ณ์ฐํ ๋ค์ 60,000๊ฐ์ ์ธ๋ฑ์ค๋ก ์ด๋ํ ๋ค์ ๋ฐ๋ณตํ๋ ค๊ณ ํฉ๋๋ค.
๋น์์๋ ๋น์ทํ ๋ฐ์ธ. ์ด ๊ฒฝ์ฐ ์ด๋ฌํ ์ ํ์ ์ฐฝ์ ๊ตฌํํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ ๋ํด ์ฝ๊ฐ์ ๋ถ์ผ์น๊ฐ ์์ ์ ์์ง๋ง ์ ์๊ฐ์๋ "๊ฐ์ฅ ์ข์"(TM) ๋ฐฉ๋ฒ์ ์๊ฐ t0๋ถํฐ ์์ํ์ฌ ๋ฒ์(t0-window , t0], ๊ธฐ๋ฅ์ ๊ณ์ฐํ ๋ค์ ๋จ๊ณ ํฌ๊ธฐ๋งํผ ์ด๋ํฉ๋๋ค. ์์์ ์ต์ ์๋ณด๋ค ์ ์ ์ฐฝ์ ๋ฒ๋ฆฝ๋๋ค(๊ตฌ์ฑ ๊ฐ๋ฅ, ๊ธฐ๋ณธ๊ฐ์ 1). ์ด ์๋ ํํ ์ฐฝ์ ๋ํ ๊ฒ์ด์ง๋ง ์์ ํ ์ ์์ต๋๋ค. ๋ชจ๋ ์ฐฝ ๊ตฌ์ฑ์ ๋ง๊ฒ.. ํฐ ๊ฐ๊ฒฉ์์ ์๊ฐ์ ๋ญ๋นํ๋ ๋จ์ ์ด ์์ง๋ง ๊ฐ๊ฒฉ์ ์ง๋ฅ์ ์ผ๋ก ์ฒ๋ฆฌ ํ ์ โโ์์ผ๋ฉฐ ์์งํ๊ฒ ๊ณ์ฐํ๋๋ผ๋ (๋์ฒ๋ผ ๊ฒ์ผ๋ฅด๋ฏ๋ก) ๋๋ ์์ง์ด ๋ฌธ์ ๋ฅผ ์ค์ ๋ก ๋ณด์ง ๋ชปํ์ต๋๋ค. , ๊ฐ๊ฒฉ์ ์ผ๋ฐ์ ์ผ๋ก ์ค์ ๋ฐ์ดํฐ์์ ์ค์ํ ๋งํผ ์ถฉ๋ถํ ํฌ์ง ์๊ธฐ ๋๋ฌธ์ YMMV.
์ด์ฉ๋ฉด ๊ทธ๊ฒ์ด ๋ ๋ช ํํฉ๋๊น? ์์ ์์ + ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ ์ ์ค๋ช ๋ ์ ์์ต๋๋ค.
@anthonytw์ ์ค๋ช
์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ค์ ๋ก step
๋ฅผ "๋จ๊ณ๋ณ"๋ก ํด์ํด์ผ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
NaN์ ๊ฒฝ์ฐ ์ถ๋ ฅ ๊ฒฐ๊ณผ์์ ์๋์ผ๋ก NaN์ ์ญ์ ํ๋ ค๋ ๊ฐ์ ์ ์ดํดํ์ง๋ง https://github.com/pandas-dev/pandas/issues/15354#issuecomment -278676420 by @jreback ์์ ์ธ๊ธํ๋ฏ์ด ์ถ๋ ฅ์ด ์
๋ ฅ๊ณผ ๋์ผํ ๊ธธ์ด๋ฅผ ๊ฐ๋๋ก ํ๊ธฐ ์ํ API ์ผ๊ด์ฑ ๊ณ ๋ ค ์ฌํญ. NaN์ ์ ์งํ๋ ค๋ ์ฌ์ฉ์๊ฐ ์์ ์ ์์ผ๋ฉฐ(์๋ง๋?) rolling(..., step=...).func()
์์
ํ์๋ dropna
๋ฅผ ๊ณ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
@mroeschke ์์ธ๊ฐ ์์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฌธ์์ ๋ช ์์ ์ผ๋ก ๋ฉ๋ชจํ๊ณ ๋์์ด ๊ธฐ๋ณธ๊ฐ์ด ์๋ ํ ์ ํฌ๋ก ๊ฐ๋ ์ฐฌ ๋ฒกํฐ๋ฅผ ๋ฐํํ์ง ์์๋ ์๋ฌด๋ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค. NaN์ ์ ์งํ๋ ๊ฒ์ ๋ชฉ์ ์ ์ ๋ฐ์ ๋ฌดํจํํฉ๋๋ค. ํ ๊ฐ์ง ๋ชฉ์ ์ ๊ฐ๋น์ผ ๊ณ์ฐ์ ์ํํ๋ ํ์๋ฅผ ์ ํํ๋ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ ๋ชฉํ๋ ๊ธฐ๋ฅ ์ธํธ๋ฅผ ๊ด๋ฆฌ ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ์ต์ํํ๋ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ์ ๊ณตํ ๊ทธ ์๋ ์ค์ ์ฌ๋ก์ด๋ฉฐ ํ์ ๋ชจ๋ํฐ๋ง ์์ฉ ํ๋ก๊ทธ๋จ์์ ์ค์ ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ ๋ฐ์ดํฐ๋งํผ ๋ง์ง ์์ต๋๋ค. ํ์ํ ๊ณต๊ฐ์ 60000๋ฐฐ๋ฅผ ํ ๋นํ ๋ค์ ์ด๋ ์ด๋ฅผ ๊ฒ์ํ์ฌ NaN์ ์ญ์ ํด์ผ ํฉ๋๊น? ๊ณ์ฐํ๋ ค๋ ๊ฐ ๊ธฐ๋ฅ์ ๋ํด?
ํ ๋ฒ์ ๊ณ์ฐ์ผ๋ก ๊ฐ ๋ฐฐ์ด์ด ์์ฑ๋ ์ ์์ต๋๋ค. ECG ํํ์ผ๋ก ๋ฌด์์ ํ๊ณ ์ถ์ต๋๊น? ๋ฌผ๋ก ์ ๋ ฅ ์คํํธ๋ผ์ ๊ณ์ฐํฉ๋๋ค! ๋ฐ๋ผ์ 1๊ฐ์ ์ ์ฒด PSD ๋ฒกํฐ(150,000๊ฐ ์์)์ 180๋ง ๋ฒ(2TB์ ๋ฐ์ดํฐ)์ ์ํ ์ถฉ๋ถํ ๊ณต๊ฐ์ ํ ๋นํ ๋ค์ ๋ด๊ฐ ๊ด์ฌ ์๋ ์กฐ๊ฐ(34MB)์ ์ป๊ธฐ ์ํด ํํฐ๋งํด์ผ ํฉ๋๋ค. ๋ชจ๋ ์๋ฆฌ์ฆ. ๋ชจ๋ ํ์๋ฅผ ์ํด. ๋จ์ ๋ ์ฌ์ผ ํ ๊ฒ ๊ฐ์์!
์ผ๋ถ ๊ธฐ๋ฅ์ ๊ฒฝ์ฐ NaN์ด ์๋ฏธ ์๋ ์ถ๋ ฅ์ด ๋ ์ ์๋ค๋ ์ ๋ ์ธ๊ธํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์๋ฏธ ์๋ NaN๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ฑ์ฐ๋ ์ ํฌ NaN์ ์ฐจ์ด๋ฅผ ๋ ์ด์ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
API๋ฅผ ์ ์งํ๋ ค๋ ์๊ตฌ๋ฅผ ์ดํดํ์ง๋ง, ์ด๊ฒ์ ๊ธฐ์กด ์ฝ๋๋ฅผ ๊นจ๋จ๋ฆฌ๋ ๊ธฐ๋ฅ์ด ์๋๋ฉฐ(์ด์ ์๋ ์กด์ฌํ์ง ์์๋ ์๋ก์ด ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์), ๊ธฐ๋ฅ์ ๊ฐ์ํ ๋ ๋๊ตฐ๊ฐ๊ฐ ์ด๋ฅผ ์ฐ์ถํ ๊ฒ์ผ๋ก ๊ธฐ๋ํ ์ด์ ๊ฐ ์์ต๋๋ค. ๊ฐ์ ํฌ๊ธฐ์ ์ถ๋ ฅ ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ๊ฒ ํ๋ ๊ฒฝ์ฐ์๋ ๋ฌธ์์ ๋จ๊ณ ํฌ๊ธฐ์ ๋ํ ๋ฉ๋ชจ๋ก ์ถฉ๋ถํ ๊ฒ์ ๋๋ค. ๋จ์ ์ "์ผ๊ด๋" API๋ฅผ ๊ฐ๋ ๊ฒ์ ์ด์ ๋ณด๋ค ํจ์ฌ ํฝ๋๋ค(์ด์ ์ ์กด์ฌํ์ง ์์๋ ๊ธฐ๋ฅ์ ๊ฒฝ์ฐ ์ฃผ์ํ์ญ์์ค). ์ด ๋ฐฉ๋ฒ์ผ๋ก ์งํํ์ง ์์ผ๋ฉด ๊ธฐ๋ฅ์ด ์์๋ ๊ฒ์ ๋๋ค. ์ด ๊ฒฝ์ฐ์๋ ๊ตฌํํ ๊ฐ์น๊ฐ ๊ฑฐ์ ์์ต๋๋ค(๋ด ๊ฒฝํ์ ๊ณต๊ฐ ๋น์ฉ์ด ๊ฑฐ์ ํญ์ ๋ ํฐ ์์์).
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
"์ด๊ฒ์ ํ ์ ์์ง๋ง ์ด๊ฒ์ด ์ค์ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ๋ณด๊ณ ์ถ์ต๋๋ค."
ํฌ๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ ํ๋ก์ ํธ๊ฐ ๋ฌด์์ด๋ ๊ฐ์ ์ด ๊ธฐ๋ฅ์ ๊ฑฐ์ ํญ์ ๋์ณค์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ๊ฐ๋์ฉ๋ง ์ ์ฉ์ ๊ณ์ฐํด์ผ ํ ๋๋ง๋ค ์ ์ฉํ์ง๋ง ์ฌ์ ํ ๊ฐ ์ฐฝ ๋ด์์ ์ข์ ํด์๋๊ฐ ํ์ํฉ๋๋ค.