본문 바로가기
프로그래밍/Python 관련 정보

[Pandas] 날짜 형식 연산하기

by TrillionNT 2025. 2. 14.

2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents


데이터프레임에서 날짜형식을 계산하다보면 어렵지는 않은데 생각보다 헷갈리는 경우가 많아서 한 번 정리해두고 업데이트 사항이 있을 때마다 덧붙이려고 합니다. 

일단 우리가 다룰 수 있는 pandas 날짜형식은 크게 2가지 정도가 있겠습니다. 

 

1. Datetime 기반 객체

특정 날짜와 시간(연월일시분초) 정보를 포함하며, 초 단위까지 세밀한 연산이 가능합니다. 

  • 시계열 데이터 (DatetimeIndex) 처리 가능
  • dt.year, dt.month, dt.day, dt.quarter 등을 활용해 특정 날짜 정보 추출
  • Timedelta를 이용한 날짜 간 차이 계산 가능
  • 연, 월, 일뿐만 아니라 시간(hour), 분(minute), 초(second) 단위까지 표현 가능
# 날짜 간 차이 계산 (Timedelta)
dt1 = pd.to_datetime("2024-01-01")
dt2 = pd.to_datetime("2023-12-01")
diff = dt1 - dt2
print(diff.days)  # 31일 차이

 

 

1) datetime 객체 생성 방법(칼럼/단일 객체 동일) : pd.to_datetime() 

: 날짜형태의 str타입 column이 있다면 명령어로 datetime형식의 칼럼으로 바꾸어주면 됩니다.

# 샘플 데이터 (A가 datetime 형식)
df = pd.DataFrame({
    'A': pd.to_datetime(['2009-01-02', '2010-05-06', '2008-12-30'])
})

 

칼럼 값이 아니라 단일 객체일 경우라도 동일한 명령어로 변환해 줄 수 있습니다.

compare_date = '2009-01-02'

# 문자열을 datetime으로 변환
compare_datetime = pd.to_datetime(compare_date)

 

기존의 column으로 datetime column을 만들어내는 것이 아니라 직접 범위 지정을 통해 column을 만들어주고 싶다면 pd.date_range를 활용해서 만들어주면 됩니다. 

# DatetimeIndex를 PeriodIndex로 변환
dt_range = pd.date_range("2024-01-01", periods=4, freq="D")

 

2) PeriodIndex로의 변환

period_range = dt_range.to_period(freq="M")  # 월 단위로 변환
print(period_range)

 

3) 대소비교 및 차이계산

대소비교는 동일하게 datetime 형식으로 바꿔놓고 진행할 수 있습니다. 

import pandas as pd

# 샘플 데이터 (A가 datetime 형식)
df = pd.DataFrame({
    'A': pd.to_datetime(['2009-01-02', '2010-05-06', '2008-12-30'])
})

# 비교할 기준 날짜 (문자열)
compare_date = '2009-01-02'

# 문자열을 datetime으로 변환
compare_datetime = pd.to_datetime(compare_date)

# 날짜 비교 (이전/이후)
df['is_later'] = df['A'] > compare_datetime
df['is_earlier'] = df['A'] < compare_datetime

print(df)
           A  is_later  is_earlier
0 2009-01-02     False       False
1 2010-05-06      True       False
2 2008-12-30     False        True

 

차이를 계산하고 싶으면 두 날짜의 차이를 timedelta 객체로 얻은 후에 days 속성을 활용하면 됩니다. 

import pandas as pd

# 샘플 데이터 생성
df = pd.DataFrame({
    'start_date': pd.to_datetime(['2024-01-01', '2024-02-01', '2024-03-01']),
    'end_date': pd.to_datetime(['2024-01-10', '2024-02-20', '2024-03-25'])
})

# 날짜 차이 계산 (timedelta 객체)
df['date_diff'] = df['end_date'] - df['start_date']

# 차이를 정수 (일 단위)로 변환
df['days_diff'] = df['date_diff'].dt.days

print(df)
   start_date   end_date date_diff  days_diff
0 2024-01-01 2024-01-10   9 days         9
1 2024-02-01 2024-02-20  19 days        19
2 2024-03-01 2024-03-25  24 days        24

 

만약 Column 간 차이가 아니라 datetime 형식의 칼럼과 string과의 비교라면 어떻게 될까요? pd.to_datetime 을 이용해서 datetime 형식으로 변환한 뒤 동일하게 적용해 주면 됩니다(대소비교도 마찬가지). 

 

2. Period 기반 객체

  • pd.Period()를 사용하여 특정 연도, 분기, 월, 주 등의 기간 단위 표현 가능
  • 초 단위 연산이 불가능하고, 연도/분기/월/주 단위 연산에 적합
  • Datetime보다 메모리 사용량이 적음
  • .year, .month, .quarter 속성을 이용하여 기간 정보 추출 가능

1) Period 객체 생성 방법

Period기반 객체는 칼럼을 변환하는 경우와 단일 객체를 변환하는 경우에 명령어가 살짝 다릅니다. 

A. 날짜 꼴의 str타입 column으로부터 PeriodIndex 생성하는 방법 : pd.to_datetime() + .dt.to_period()사용

    (혹은 pd.to_datetime() + pd.PeriodIndex(    , freq=  ) 사용)

import pandas as pd

# 샘플 데이터 (문자열 형태의 날짜 리스트)
df = pd.DataFrame({
    'date_str': ['2024-01-01', '2024-02-01', '2024-03-01']
})

# 문자열 → datetime → Period 변환 (월 단위)
df['date_period'] = pd.to_datetime(df['date_str']).dt.to_period('M')

# 문자열 → datetime → Period 변환 (분기 단위)
df['date_period_Q'] = pd.to_datetime(df['date_str']).dt.to_period('Q')

print(df)
      date_str date_period date_period_Q
0  2024-01-01     2024-01        2024Q1
1  2024-02-01     2024-02        2024Q1
2  2024-03-01     2024-03        2024Q1

 

B. 단일 객체의 변환 : pd.Period()

p1 = pd.Period("2024Q1", freq="Q")

 

기존의 column으로 Period column을 만들어내는 것이 아니라 직접 범위 지정을 통해 column을 만들어주고 싶다면 pd.period_range를 활용해서 만들어주면 됩니다. 

p_range = pd.period_range("2024Q1", periods=4, freq="Q")

 

2) Datetime으로의 변환

# PeriodIndex를 DatetimeIndex로 변환
p_range = pd.period_range("2024Q1", periods=4, freq="Q")
dt_from_period = p_range.to_timestamp()
print(dt_from_period)  # ['2024-01-01', '2024-04-01', '2024-07-01', '2024-10-01']

 

3) 대소비교 및 차이계산

이번에는 Period 객체 간 차이는 어떻게 구할까요? 일단 대소나 차이비교를 위한 두 대상을 모두 Period 타입으로 바꿔주는 것은 동일합니다. 그리고 단순 뺄셈을 이용해서 차를 구하면 Period type끼리의 차이는 Period 객체를 반환하기 때문에 <QuarterEnd: startingMonth=12> 와 같은 형태의 값이 얻어집니다. 이를 원하는 정수값으로 얻기 위해서는 .n 속성을 활용하면 됩니다. 

import pandas as pd

# 샘플 데이터 (PeriodIndex 형식)
df = pd.DataFrame({
    'A_date': pd.period_range('2009Q1', '2010Q4', freq='Q'),
    'B_date': pd.period_range('2008Q1', '2009Q4', freq='Q')
})

df['quarter_diff'] = df['A_date'] - df['B_date']
print(df['quarter_diff'].apply(lambda x: x.n))
import pandas as pd

# 샘플 데이터 (A_date가 PeriodIndex 형식)
df = pd.DataFrame({
    'A_date': pd.period_range('2009Q1', '2011Q4', freq='Q')  # 2009Q1 ~ 2011Q4
})

# 비교할 기준 값 (문자열)
compare_date_str = '2008Q1'

# 문자열을 Period 객체로 변환
compare_period = pd.Period(compare_date_str, freq='Q')

# Period 객체 간 차이 계산 후, .n으로 정수 값 추출
df['quarter_diff'] = (df['A_date'] - compare_period).apply(lambda x: x.n)

print(df)