[Pandas] shift / diff / pct_change
Pandas shift / diff, Pandas shift, Pandas diff, Pandas pct_change, 시차 pandas
정의
shift(n): 값을 n 칸 밀기 (lag/lead)diff(n): n 칸 차이 (=s - s.shift(n))pct_change(n): 변화율 (=s.diff(n) / s.shift(n))
시계열 분석의 기본 도구. 전일 대비 / 전월 대비 / 누적 증가율 등.
shift
s.shift(1) # 한 칸 아래로 (lag, NaN 채움)
s.shift(-1) # 한 칸 위로 (lead)
s.shift(7) # 일주일 전 값
s.shift(1, fill_value=0) # NaN 대신 0
python
import pandas as pd
s = pd.Series([10, 12, 15, 14, 18])
print('original:', s.tolist())
print('shift(1):', s.shift(1).tolist())
print('shift(-1):', s.shift(-1).tolist()) 결과
original: [10, 12, 15, 14, 18]
shift(1): [nan, 10.0, 12.0, 15.0, 14.0]
shift(-1): [12.0, 15.0, 14.0, 18.0, nan]| index | s | shift(1) | shift(-1) |
|---|---|---|---|
| 0 | 10 | NaN | 12 |
| 1 | 12 | 10 | 15 |
| 2 | 15 | 12 | 14 |
| 3 | 14 | 15 | 18 |
| 4 | 18 | 14 | NaN |
diff
s.diff() # = s - s.shift(1), 1차 차분
s.diff(2) # 2 step 차분
python
import pandas as pd
s = pd.Series([10, 12, 15, 14, 18])
print(s.diff().tolist())
print(s.diff(2).tolist()) 결과
[nan, 2.0, 3.0, -1.0, 4.0]
[nan, nan, 5.0, 2.0, 3.0]pct_change (변화율)
s.pct_change() # 직전 대비 비율 변화
s.pct_change(7) # 7 step 변화율 (주간 단위 등)
python
import pandas as pd
s = pd.Series([100, 120, 144, 180])
print(s.pct_change().round(3).tolist()) 결과
[nan, 0.2, 0.2, 0.25]20% → 20% → 25% 증가.
time-based shift
DatetimeIndex 일 때 freq 지정 가능.
s.shift(1, freq='D') # 1 일 이동
s.shift(-1, freq='ME') # 한 달 전
자주 쓰는 패턴
전월 대비 매출
df['mom'] = df['monthly_sales'].pct_change()
lag features (ML)
df['sales_lag1'] = df['sales'].shift(1)
df['sales_lag7'] = df['sales'].shift(7)
df['sales_lag30'] = df['sales'].shift(30)
룩어헤드 방지
# 오늘 데이터로 내일을 예측하는 모델
df['target'] = df['close'].shift(-1) # 내일 close
# 학습 feature 는 shift 안 함
누적 증가율
df['cumulative_return'] = (1 + df['daily_return']).cumprod()
그룹별 shift
df['prev_amount'] = df.groupby('user_id')['amount'].shift(1)
# 같은 user 안에서 이전 주문
함정
1. NaN 의 첫/마지막
shift(1) 은 처음에 NaN, shift(-1) 은 마지막에 NaN. dropna() 또는 fill_value 처리 필요.
2. 시간 freq 가 일정하지 않을 때
# index 가 불규칙 시계열
df.shift(1) # 위치 기반, 실제 시간 차이는 다양
df.shift(1, freq='D') # 시간 기반, 매핑 안 되면 NaN
3. groupby + shift 의 정렬
df = df.sort_values(['user_id', 'date'])
df['prev'] = df.groupby('user_id')['amount'].shift(1)
정렬이 안 된 상태에서 shift 하면 의미가 달라진다.
참고
이 글의 용어 (3개)
- [Pandas] cumsum / cummax / cummin / cumprodpandas
- 정의 누적 (cumulative) 연산. 각 위치까지의 누적 결과를 반환, 결과 길이는 원본과 동일. | 함수 | 의미 | |:---|:---| | | 누적 합 | | | 누적 …
- [Pandas] resamplepandas
- 정의 는 시계열 데이터를 다른 빈도 (월별, 일별, 시간별 등) 로 재샘플링하면서 집계한다. 의 시계열 버전. DatetimeIndex (또는 으로 datetime 컬럼) 이 필…
- [Pandas] rolling / expandingpandas
- 정의 - : 고정 크기 슬라이딩 윈도우 (이동 평균 등) - : 시작부터 누적 윈도우 (cumulative) - : 지수 가중 이동 평균 시각화 rolling 기본 <CodeWi…
💬 댓글