API · Pandas

Pandas DataFrame.rolling() 함수

DataFrame rolling() 함수는 수학적 연산을위한 롤링 창을 제공합니다.

이 페이지의 내용

Python Pandas DataFrame.rolling() 함수는 수학적 연산을 위한 롤링 창을 제공합니다. rolling()을 호출하는 것만으로는 아무것도 계산되지 않습니다. 이동 창을 정의하는 Rolling 객체를 반환하고, sum(), mean(), std()와 같은 집계 메서드가 각 창을 하나의 결과 행으로 축소합니다. 창은 일반적으로 현재 행에서 끝나므로 결과는 원래 DataFrame과 동일한 인덱스를 유지합니다. 이것이 rolling()이 누적 합계, 이동 평균 및 기타 실행 통계를 구축하는 표준 방법인 이유입니다.

pandas.DataFrame.rolling()의 구문

DataFrame.rolling(
    window, min_periods=None, center=False, win_type=None, on=None,
    closed=None, step=None, method='single'
)

매개변수

window 정수, 오프셋 또는 BaseIndexer 하위 클래스인 매개변수입니다. 이동 창의 크기를 지정합니다. 고정된 관측 수이거나, 오프셋을 사용할 경우 '3D'와 같은 시간 범위입니다.
min_periods 정수 매개변수입니다. 창 안에 필요한 NaN이 아닌 관측의 최소 개수를 지정합니다. 그보다 적은 관측을 가진 창은 NaN을 반환합니다. 설정하지 않으면 기본값은 고정 창의 경우 창 크기와 같고, 시간 기반 창의 경우 1입니다.
center 부울 매개변수입니다. True이면 각 결과가 오른쪽 가장자리가 아닌 창의 중앙에 레이블이 지정됩니다.
win_type 문자열 매개변수입니다. 'triang'와 같은 가중 창 유형을 지정하여 창 안의 관측이 서로 다른 가중치로 기여합니다. 대부분의 가중 창 유형에는 SciPy가 필요합니다.
on 문자열 매개변수입니다. 인덱스 대신 롤링 창을 계산할 열 이름을 지정합니다. 날짜가 열에 저장된 시간 기반 창에 사용됩니다.
closed 문자열 매개변수입니다. 창 구간의 어느 쪽이 닫혀 있는지를 지정합니다. right, left, both, neither의 네 가지 옵션이 있습니다. 기본값은 right입니다.
step 정수 매개변수입니다. 창은 step 행마다 평가되므로 결과에는 해당 행만 포함됩니다.

반환

Rolling 창 객체를 반환합니다. 여기에 집계 메서드를 호출하면 입력과 동일한 인덱스를 가진 DataFrame이 반환됩니다.

위의 서명은 현재 서명입니다. 오래된 튜토리얼에 나오는 axis 매개변수는 롤링 창이 항상 인덱스를 따라 이동하므로 더 이상 존재하지 않습니다. 이를 전달하면 아래 오류 섹션에서 볼 수 있듯이 TypeError가 발생합니다.

예제: 크기가 2인 고정 창을 사용한 롤링 합계

가장 일반적인 형식은 행을 세는 정수 창을 사용하는 것입니다. 이 예제에서 rolling(2).sum()은 각 행을 바로 위의 행에 더합니다.

import pandas as pd

dataframe = pd.DataFrame({
    'Attendance': {0: 60, 1: 100, 2: 80, 3: 78, 4: 95},
    'Obtained Marks': {0: 90, 1: 75, 2: 82, 3: 64, 4: 45},
})
print("The Original DataFrame is:")
print(dataframe)
print("The Rolling Sum With a Window of 2 is:")
print(dataframe.rolling(2).sum())

출력:

The Original DataFrame is:
   Attendance  Obtained Marks
0          60              90
1         100              75
2          80              82
3          78              64
4          95              45
The Rolling Sum With a Window of 2 is:
   Attendance  Obtained Marks
0         NaN             NaN
1       160.0           165.0
2       180.0           157.0
3       158.0           146.0
4       173.0           109.0

행 0에는 위에 행이 없으므로 그 창에는 관측이 하나만 포함됩니다. 이는 기본 min_periods가 요구하는 두 개보다 적으므로 결과는 NaN입니다. 행 1부터 각 값은 현재 행과 이전 행의 합입니다. 60 + 100 = 160, 100 + 80 = 180과 같은 방식입니다. 정수 열은 이 첫 번째 NaN 때문에 float가 됩니다.

예제: 롤링 평균과 min_periods

동일한 창은 모든 집계와 함께 작동합니다. 여기에서 rolling(3).mean()은 현재 행과 그 위의 두 행의 평균을 구합니다. 기본 min_periods에서는 처음 두 행이 세 행짜리 창을 채울 수 없어 NaN으로 남습니다. min_periods=1로 설정하면 pandas가 시작 부분에서 사용할 수 있는 관측 수만큼만으로 작업하므로 결과는 첫 번째 행부터 정의됩니다.

import pandas as pd

dataframe = pd.DataFrame({
    'Attendance': {0: 60, 1: 100, 2: 80, 3: 78, 4: 95},
    'Obtained Marks': {0: 90, 1: 75, 2: 82, 3: 64, 4: 45},
})
print("The Rolling Mean With a Window of 3 is:")
print(dataframe.rolling(3).mean())
print("The Rolling Mean With a Window of 3 and min_periods=1 is:")
print(dataframe.rolling(3, min_periods=1).mean())

출력:

The Rolling Mean With a Window of 3 is:
   Attendance  Obtained Marks
0         NaN             NaN
1         NaN             NaN
2   80.000000       82.333333
3   86.000000       73.666667
4   84.333333       63.666667
The Rolling Mean With a Window of 3 and min_periods=1 is:
   Attendance  Obtained Marks
0   60.000000       90.000000
1   80.000000       82.500000
2   80.000000       82.333333
3   86.000000       73.666667
4   84.333333       63.666667

두 출력은 인덱스 2부터 일치합니다. 차이는 맨 위에 있습니다. min_periods=1은 첫 번째 행에 대해 60.00(그 값 자체)을, 두 번째 행에 대해 80.00(처음 두 값의 평균)을 추가로 보고합니다. min_periods는 NaN이 아닌 관측을 센다는 점에 유의하세요. 이 때문에 마지막 예에서 볼 수 있듯이 데이터 내부의 간격에 대한 주요 제어 수단이기도 합니다.

예제: 시간 기반 창을 사용한 롤링 합계

window는 '3D'와 같은 시간 오프셋일 수도 있습니다. 그러면 창은 고정된 행 수가 아닌 시간 범위를 포함하므로, 레코드는 간격이 아무리 불규칙하더라도 범위 안에 들어갈 때만 기여합니다. 날짜가 인덱스가 아닌 열에 있을 경우 on으로 해당 열을 지정하세요. 아래 매출에는 2026-01-04와 2026-01-07에 대한 레코드가 없습니다.

import pandas as pd

sales = pd.DataFrame({
    'Date': pd.to_datetime(['2026-01-01', '2026-01-02', '2026-01-03',
                            '2026-01-05', '2026-01-06', '2026-01-08']),
    'Sales': [120, 80, 150, 90, 200, 60],
})
print(sales)
print("The Rolling Sum Over the Previous 3 Days is:")
print(sales.rolling('3D', on='Date').sum())

출력:

        Date  Sales
0 2026-01-01    120
1 2026-01-02     80
2 2026-01-03    150
3 2026-01-05     90
4 2026-01-06    200
5 2026-01-08     60
The Rolling Sum Over the Previous 3 Days is:
        Date  Sales
0 2026-01-01  120.0
1 2026-01-02  200.0
2 2026-01-03  350.0
3 2026-01-05  240.0
4 2026-01-06  290.0
5 2026-01-08  260.0

2026-01-05의 경우 3일 창은 2026-01-02 이전까지 거슬러 올라가므로 2026-01-03과 2026-01-05의 매출만 포함합니다. 150 + 90 = 240입니다. 누락된 2026-01-04는 아무것도 기여하지 않으며, 추가 행이 고정 창을 이동시키는 것처럼 범위를 이동시키지 않습니다. 첫 번째 행에 이미 결과가 있다는 점에도 유의하세요. 시간 기반 창은 기본적으로 min_periods=1을 사용하며, 이는 고정 창과는 반대의 기본값입니다.

예제: center로 레이블을 중앙에 배치하고 closed로 현재 행 제외하기

두 개의 매개변수는 결과가 속하는 위치를 변경합니다. center=True를 사용하면 집계된 값이 마지막 행이 아닌 창의 가운데 행에 배치되며, 이는 이동 평균이 평활화하는 데이터와 정렬되어야 할 때 원하는 동작입니다. 처음 행과 마지막 행은 완전한 창이 그 행들을 중심으로 배치될 수 없으므로 결과를 잃습니다. closed는 구간 끝 중 어느 쪽이 포함되는지를 제어합니다. closed='left'를 사용하면 한 행의 창은 그 행보다 앞선 행들을 포함하고, 행 자체는 자체 통계에서 제외됩니다.

import pandas as pd

temps = pd.DataFrame({'Temperature': [10, 12, 14, 16, 18, 20]})
print("The Centered Rolling Mean With a Window of 3 is:")
print(temps.rolling(3, center=True).mean())
print("The Rolling Sum With a Window of 3 and closed='left' is:")
print(temps.rolling(3, closed='left').sum())

출력:

The Centered Rolling Mean With a Window of 3 is:
   Temperature
0          NaN
1         12.0
2         14.0
3         16.0
4         18.0
5          NaN
The Rolling Sum With a Window of 3 and closed='left' is:
   Temperature
0          NaN
1          NaN
2          NaN
3         36.0
4         42.0
5         48.0

인덱스 1의 중앙 평균은 12.0, 즉 10, 12, 14의 평균이며, 해당 창의 가운데 행에 위치합니다. closed='left' 합계는 익숙한 36, 42, 48 패턴이 한 행 아래로 이동한 모습을 보여줍니다. 인덱스 3에서 창은 행 0부터 2까지(10 + 12 + 14 = 36)를 포함하는데, 이는 행 3 자체가 제외되기 때문입니다.

일반적인 오류 및 경계 사례

사용자를 가장 자주 놀라게 하는 세 가지 동작이 있으며, 각각은 작은 예제에서 확인할 수 있습니다.

창 내부의 누락된 값

min_periods는 NaN이 아닌 관측을 세므로, 누락된 값 하나가 그것을 포함하는 모든 고정 창과 그 뒤에 오는 창을 비웁니다. min_periods를 낮추면 집계가 존재하는 값을 사용합니다.

import pandas as pd

scores = pd.DataFrame({'Score': [50.0, None, 70.0, 90.0]})
print(scores)
print("The Rolling Sum With a Window of 2 is:")
print(scores.rolling(2).sum())
print("The Rolling Sum With a Window of 2 and min_periods=1 is:")
print(scores.rolling(2, min_periods=1).sum())

출력:

   Score
0   50.0
1    NaN
2   70.0
3   90.0
The Rolling Sum With a Window of 2 is:
   Score
0    NaN
1    NaN
2    NaN
3  160.0
The Rolling Sum With a Window of 2 and min_periods=1 is:
   Score
0   50.0
1   50.0
2   70.0
3  160.0

기본 설정에서는 마지막 합계인 70 + 90만 살아남습니다. min_periods=1을 사용하면 인덱스 2의 창에는 유효한 값이 하나 포함되어 있으므로 그 합계는 70입니다. 누락된 항목은 전파되지 않고 건너뜁니다. 어느 동작도 데이터를 복구하지는 않습니다. 부분 창이 통계에 의미가 있는지를 기준으로 둘 중 하나를 선택하세요.

잘못된 인수는 ValueError를 발생시킵니다

rolling()은 무엇이든 계산하기 전에 인수를 검증합니다. 음수 창은 즉시 실패합니다.

import pandas as pd

temps = pd.DataFrame({'Temperature': [10, 12, 14, 16, 18, 20]})
print(temps.rolling(-1).sum())

출력:

ValueError: window must be an integer 0 or greater

알 수 없는 closed 값도 같은 방식으로 실패하며, 메시지는 ValueError: closed must be 'right', 'left', 'both' or 'neither'입니다. 2.5와 같은 소수 창은 음수 창과 같은 메시지로 거부됩니다. window=0은 허용되지만 퇴화되어 있습니다. 모든 창이 비어 있으므로 sum()은 모든 행에 대해 0.0을 반환합니다.

숫자가 아닌 열은 DataError를 발생시킵니다

집계는 숫자 데이터만 허용합니다. 텍스트 열이 여전히 포함된 DataFrame에 롤링을 적용하면 오류가 발생합니다.

import pandas as pd

mixed = pd.DataFrame({'Name': ['A', 'B', 'C'], 'Value': [1, 2, 3]})
print(mixed.rolling(2).sum())

출력:

pandas.errors.DataError: Cannot aggregate non-numeric type: str

롤링하기 전에 숫자 열을 선택하세요(예: mixed[['Value']].rolling(2).sum()) — 또는 레이블 열을 먼저 제거하세요.

유의해야 할 사항

  • rolling() 자체는 Rolling 객체를 반환합니다. 집계 메서드가 호출될 때까지는 아무것도 계산되지 않습니다. 결과는 항상 입력의 인덱스를 가지므로 새 열로 바로 할당할 수 있습니다.
  • 출력에 NaN이 나타나자마자 정수 열은 float가 됩니다. NaN에는 정수 표현이 없기 때문입니다.
  • 그룹화된 계산의 경우 df.groupby('key').rolling(2).sum()과 같이 groupby 객체에 대해 rolling()을 호출하세요. 그러면 창이 그룹 경계를 넘는 대신 각 그룹마다 다시 시작합니다.
  • win_type을 통한 가중 창은 신호 형태의 데이터를 위한 것입니다. 일반적인 비즈니스 데이터에서는 위 예제의 가중 없는 집계가 올바른 기본값입니다.