Pandas: ๋‹จ๊ณ„ ํฌ๊ธฐ๊ฐ€ ์žˆ๋Š” ๋กค๋ง ์ฐฝ

์— ๋งŒ๋“  2017๋…„ 02์›” 09์ผ  ยท  38์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pandas-dev/pandas

๊ทธ๋ƒฅ ์ œ์•ˆ - 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

Enhancement Needs Discussion Numeric Window

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

"์ด๊ฒƒ์€ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ์ค‘์š”ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค."

ํŒฌ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…ํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ฌด์—‡์ด๋“  ๊ฐ„์— ์ด ๊ธฐ๋Šฅ์„ ๊ฑฐ์˜ ํ•ญ์ƒ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๊ฐ€๋”์”ฉ๋งŒ ์ ์šฉ์„ ๊ณ„์‚ฐํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ์œ ์šฉํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ฐ ์ฐฝ ๋‚ด์—์„œ ์ข‹์€ ํ•ด์ƒ๋„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  38 ๋Œ“๊ธ€

'ํ‘œ์ค€' ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ฒกํ„ฐํ™”๋˜๋ฏ€๋กœ 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)

rolling window

@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์ดˆ ์—ฐ์žฅ๋จ).
rolling_with_step_using_resample

์ด๋Š” ์ง‘๊ณ„ ์œ ํ˜•์— ๋”ฐ๋ผ ์—ฌ์ „ํžˆ ๋‹ค์†Œ ๋‚ญ๋น„์ž…๋‹ˆ๋‹ค. @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) ๋ชจ์–‘์˜ ๋ฐฐ์—ด์—์„œ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

image

"์ด๊ฒƒ์€ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ์ค‘์š”ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค."

ํŒฌ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…ํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ฌด์—‡์ด๋“  ๊ฐ„์— ์ด ๊ธฐ๋Šฅ์„ ๊ฑฐ์˜ ํ•ญ์ƒ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๊ฐ€๋”์”ฉ๋งŒ ์ ์šฉ์„ ๊ณ„์‚ฐํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ์œ ์šฉํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ฐ ์ฐฝ ๋‚ด์—์„œ ์ข‹์€ ํ•ด์ƒ๋„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ €๋„ ์ด ๊ธฐ๋Šฅ์— ๋™์˜ํ•˜๊ณ  ์ง€์ง€ํ•ฉ๋‹ˆ๋‹ค

์‹œ๊ณ„์—ด์„ ๋‹ค๋ฃฐ ๋•Œ ๊ฑฐ์˜ ๋งค๋ฒˆ ํ•„์š”๋กœ ํ•˜๋Š” ์ด ๊ธฐ๋Šฅ์€ ์‹œ๊ฐํ™”์™€ ๋ถ„์„ ๋ชจ๋‘๋ฅผ ์œ„ํ•œ ์‹œ๊ณ„์—ด ๊ธฐ๋Šฅ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ํ›จ์”ฌ ๋” ๋‚˜์€ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์•„์ด๋””์–ด๋ฅผ ์ ๊ทน ์ง€์›ํ•˜์‹ญ์‹œ์˜ค!

์ด ๊ธฐ๋Šฅ์— ๋™์˜ํ•˜๊ณ  ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ข‹์€ ์ฐฝ ํ•ด์ƒ๋„๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ณ„์‚ฐ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ๋ฐ ๋งค์šฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํŠน์ • ๋Œ€์ƒ์— ๋”ฐ๋ผ ์ถ”๊ฐ€๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์†”๋ฃจ์…˜ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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 ๋ฒˆ์งธ๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ฐฝ ํฌ๊ธฐ๋Š” ํ”„๋กœ๊ทธ๋žจ ์ˆ˜๋ช… ๋™์•ˆ ๊ฐ€๋ณ€์ ์ด๋ฉฐ ๋‹จ๊ณ„๋Š” ์ฐฝ ํฌ๊ธฐ์˜ ์ •์ˆ˜ ๋น„์œจ์ด ๋˜๋„๋ก ๋ณด์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€๊ธˆ๊นŒ์ง€ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ฐพ์€ ๋ชจ๋“  ์†”๋ฃจ์…˜์—์„œ ๋ถˆ๊ฐ€๋Šฅํ•œ "๋ณด๊ณ  ์žˆ๋Š” ์—ฐ๋„์˜ ์ผ ์ˆ˜"๋งŒํผ ์„ค์ •๋œ ์ฐฝ ํฌ๊ธฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋งฅ๋ฝ์—์„œ ๋น„์Šทํ•œ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์‹ค์ œ์ ์ด๊ณ  ์ „๋ฌธ์ ์ธ ํ•„์š”์— ๋”ฐ๋ผ ์กฐ์ •๋จ).

  • ํƒ€์ž„์Šคํƒฌํ”„ ์—ด๊ณผ ๋ถˆ๊ทœ์น™ํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’ ์—ด์ด ์žˆ๋Š” ์‹œ๊ฐ„์ˆœ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๊ฐ€ ๋‚ด ์ฐฝ๋ฌธ ์•„๋ž˜๋กœ ์ง€๋‚˜๊ฐˆ ๋•Œ์˜ ํƒ€์ž„ ์Šคํƒฌํ”„์™€ ๊ทธ๋…€๊ฐ€ ํ†ต๊ณผํ•˜๋Š” ๋ฐ ๋ช‡ ์ดˆ๊ฐ€ ๊ฑธ๋ ธ๋Š”์ง€์ฒ˜๋Ÿผ. ์ฃผ์–ด์ง„ ๋‚ ์— 6๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ  ๋‹ค์Œ 2์ผ ๋™์•ˆ ์ด๋ฒคํŠธ๊ฐ€ ์ „ํ˜€ ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • 30์ผ๋งˆ๋‹ค ๋กค๋ง๋˜๋Š” 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๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์˜ ์ด์ ๋ณด๋‹ค ํ›จ์”ฌ ํฝ๋‹ˆ๋‹ค(์ด์ „์— ์กด์žฌํ•˜์ง€ ์•Š์•˜๋˜ ๊ธฐ๋Šฅ์˜ ๊ฒฝ์šฐ ์ฃผ์˜ํ•˜์‹ญ์‹œ์˜ค). ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์ง„ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋Šฅ์ด ์†์ƒ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ๊ตฌํ˜„ํ•  ๊ฐ€์น˜๊ฐ€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค(๋‚ด ๊ฒฝํ—˜์ƒ ๊ณต๊ฐ„ ๋น„์šฉ์ด ๊ฑฐ์˜ ํ•ญ์ƒ ๋” ํฐ ์š”์†Œ์ž„).

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰