본문으로 건너뛰기
김신건의 로그

[Pandas] date_range / Timestamp

· 수정 · 📖 약 1분 · 522자/단어 #python #pandas #datetime #date-range
Pandas date_range, pd.date_range, Pandas Timestamp, Pandas Timedelta

정의

  • pd.date_range : 정해진 시작/끝/간격으로 datetime 시퀀스 생성
  • pd.Timestamp : pandas 의 단일 datetime 객체
  • pd.Timedelta : 시간 차이

사용 상황

상황사용 API
보고 기간 목록 생성pd.date_range('2024-01', '2024-12', freq='MS')
DataFrame 의 누락 날짜 채우기.reindex(date_range, fill_value=0)
두 날짜의 차이 계산Timestamp - Timestamp -> Timedelta
영업일 목록 추출pd.date_range(start, end, freq='B')
월 단위 더하기Timestamp + DateOffset(months=3)
DatetimeIndex 용 인덱스 생성pd.date_range(...) -> .set_index(...)

시각화

pandas 의 datetime 타입 계층:

flowchart TD
    PD["pandas datetime 생태계"]
    PD --> TS["pd.Timestamp: 단일 시점"]
    PD --> TD["pd.Timedelta: 시간 차이"]
    PD --> DO["pd.DateOffset: 달력 기반 오프셋"]
    PD --> PP["pd.Period: 기간 구간"]
    PD --> DR["pd.date_range: 시퀀스 생성"]
    DR --> DTI["DatetimeIndex: 시계열 인덱스"]
    TS --> Op["Timestamp +/- Timedelta -> Timestamp"]
    TS --> Op2["Timestamp +/- DateOffset -> Timestamp"]

date_range 파라미터 조합:

flowchart LR
    P1["start + end + freq"] --> R1["날짜 범위 내 등간격"]
    P2["start + periods + freq"] --> R2["시작부터 N개"]
    P3["end + periods + freq"] --> R3["종료 전 N개"]
    P1 --> Warn["periods 와 동시 사용 불가"]

date_range

pd.date_range(start='2024-01-01', end='2024-01-31', freq='D')
pd.date_range(start='2024-01-01', periods=10, freq='D')
pd.date_range(end='2024-01-31', periods=10, freq='D')

start, end, periods, freq3 개 만 지정.

python
import pandas as pd
idx = pd.date_range('2024-01-01', periods=5, freq='D')
print(idx)
print('---')
print(pd.date_range('2024-01-01', '2024-01-31', freq='W'))
결과
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
             '2024-01-05'],
            dtype='datetime64[ns]', freq='D')
---
DatetimeIndex(['2024-01-07', '2024-01-14', '2024-01-21', '2024-01-28'], dtype='datetime64[ns]', freq='W-SUN')

freq 옵션 (대표)

freq의미
D매일
B영업일
W, W-MON매주 (요일 지정 가능)
MS, ME월초/월말
QS, QE분기초/분기말
YS, YE연초/연말
h, 30min, 15s시간 단위 (숫자 prefix 가능)
2D, 3W곱셈

tz 지정

pd.date_range('2024-01-01', periods=10, freq='D', tz='Asia/Seoul')
pd.date_range('2024-01-01', periods=10, freq='D', tz='UTC')

Timestamp 생성

pd.Timestamp('2024-01-15')
pd.Timestamp('2024-01-15 14:30:00', tz='Asia/Seoul')
pd.Timestamp(year=2024, month=1, day=15)
pd.Timestamp.now()
pd.Timestamp.today()      # 같음 (now 와 거의 동일)

연산

ts = pd.Timestamp('2024-01-15')
ts + pd.Timedelta(days=10)         # 2024-01-25
ts + pd.DateOffset(months=1)       # 2024-02-15 (월 단위)
ts - pd.Timestamp('2023-12-25')    # Timedelta('21 days')

Timedelta 는 정해진 시간, DateOffset 은 달력 단위 (월 길이 다름 고려).

Timedelta

pd.Timedelta(days=5, hours=3)
pd.Timedelta('1 days 02:00:00')
pd.to_timedelta(['1d', '2h', '30min'])

period (기간)

p = pd.Period('2024-01', freq='M')
p.start_time, p.end_time
p + 1                                # 2024-02
pd.period_range('2024-01', periods=12, freq='M')   # 12 개월

Timestamp 는 한 순간, Period 는 구간 (시작-끝).

DatetimeIndex 의 슬라이싱

df = pd.DataFrame(..., index=pd.date_range('2024-01-01', periods=100))
df['2024-02']
df['2024-02-15':'2024-03-15']
df.loc['2024-02-15':'2024-03-15']

자주 쓰는 패턴

보고 기간 생성

report_dates = pd.date_range('2024-01-01', '2024-12-31', freq='MS')
for d in report_dates:
    run_monthly_report(d)

누락된 날짜 채우기

full_range = pd.date_range(df.index.min(), df.index.max(), freq='D')
df = df.reindex(full_range, fill_value=0)

영업일 계산

pd.date_range('2024-01-01', '2024-01-31', freq='B')   # 영업일만

특정 요일의 날짜만

# 매주 월요일
pd.date_range('2024-01-01', '2024-03-31', freq='W-MON')

# 매월 마지막 영업일
pd.date_range('2024-01-01', '2024-12-31', freq='BME')

DataFrame 에 날짜 인덱스 붙이기

idx = pd.date_range('2024-01-01', periods=len(df), freq='D')
df.index = idx

두 날짜 사이 영업일 수

bdays = pd.bdate_range('2024-01-01', '2024-01-31')
print(f"영업일 수: {len(bdays)}")

날짜 오프셋 종류

오프셋의미
DateOffset(days=n)n일 후
DateOffset(months=n)n개월 후 (달력 기준)
DateOffset(years=n)n년 후
BDay(n)n 영업일 후
MonthEnd(n)n번째 월말
MonthBegin(n)n번째 월초
BusinessMonthEnd(n)n번째 영업 월말
from pandas.tseries.offsets import MonthEnd, BDay

ts = pd.Timestamp('2024-01-15')
ts + MonthEnd(1)    # 2024-01-31 (이번 달 말일)
ts + MonthEnd(2)    # 2024-02-29 (다음 달 말일)
ts + BDay(5)        # 5 영업일 후

함정

1. freq 가 정해지지 않은 경우

pd.DatetimeIndex(['2024-01-01', '2024-01-15', '2024-01-30'])
# freq=None, resample 등 일부 동작이 제한

명시적 freq 가 필요하면 .asfreq('D').

2. DateOffset vs Timedelta

pd.Timestamp('2024-01-31') + pd.Timedelta(days=30)     # 2024-03-01
pd.Timestamp('2024-01-31') + pd.DateOffset(months=1)   # 2024-02-29 (윤년)

월/년 단위는 DateOffset, 절대 시간은 Timedelta.

3. periods 계산

pd.date_range('2024-01-01', '2024-01-31', freq='D')
# 31 개 (양쪽 inclusive)

4. naive vs tz-aware 혼합

ts_naive = pd.Timestamp('2024-01-01')
ts_aware = pd.Timestamp('2024-01-01', tz='UTC')

ts_naive + ts_aware   # TypeError: cannot mix tz-naive and tz-aware

WARNING

tz-naive 와 tz-aware Timestamp 는 더하거나 비교할 수 없다. 처음부터 통일하거나 tz_localize / tz_convert 로 변환 후 사용.

5. Timedelta 와 DateOffset 의 차이

ts = pd.Timestamp('2024-01-31')

ts + pd.Timedelta(days=30)          # 2024-03-01 (정확히 30일)
ts + pd.DateOffset(months=1)        # 2024-02-29 (1개월 후 = 2월 말)

월/년 단위 이동에는 반드시 DateOffset. Timedelta 는 절대 시간 단위라 달력 의미가 없다.

관련 위키

이 글의 용어 (5개)
[Pandas] .dt accessorpandas
정의 는 datetime Series 의 각 구성요소 (년/월/일/시/분/요일 등) 에 벡터로 접근하는 accessor. 의 datetime 버전. 구성요소 분류 시각화 기본 컴…
[Pandas] groupbypandas
정의 는 데이터를 그룹으로 나누고 (split), 각 그룹에 함수를 적용 (apply), 결과를 합쳐 (combine) 새 DataFrame 으로 만드는 split-apply-c…
[Pandas] resamplepandas
정의 는 시계열 데이터를 다른 빈도 (월별, 일별, 시간별 등) 로 재샘플링하면서 집계한다. 의 시계열 버전. DatetimeIndex (또는 으로 datetime 컬럼) 이 필…
[Pandas] rolling / expandingpandas
정의 - : 고정 크기 슬라이딩 윈도우 (이동 평균 등) - : 시작부터 누적 윈도우 (cumulative) - : 지수 가중 이동 평균 사용 상황 | 상황 | 적합한 방법 | …
[Pandas] to_datetimepandas
정의 는 문자열, 정수, dict, DataFrame 컬럼을 타입으로 변환한다. pandas 시계열 작업의 출발점. 사용 상황 - CSV 로드 후 날짜 컬럼이 (문자열) 로 읽혔…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기