파싱

파싱 (Parsing)

시계열 데이터를 다룰 때 가장 먼저 부딪히는 일이 문자열로 된 날짜를 실제 날짜/시간 타입으로 바꾸는 거예요. Polars는 시계열 데이터를 파싱하고, 시간 기반 그룹핑이나 리샘플링 같은 더 정교한 연산을 기본으로 지원합니다. 이 섹션에서는 Polars의 시간 데이터 타입과, 파일에서 날짜를 읽고 문자열을 날짜로 변환하는 방법을 살펴볼게요.

출처: 공식문서

Polars는 시계열 데이터를 파싱하고 시간 기반 그룹핑과 리샘플링 같은 더 정교한 연산을 수행하는 것을 기본적으로 지원해요.

데이터 타입 (Datatypes)

Polars는 다음과 같은 날짜시간(datetime) 데이터 타입을 가집니다:

  • Date: 날짜 표현. 예: 2014-07-08. 내부적으로는 UNIX epoch 이후의 일(days) 수로 표현되며, 32비트 부호 정수로 인코딩됩니다.
  • Datetime: 날짜시간 표현. 예: 2014-07-08 07:00:00. 내부적으로는 UNIX epoch 이후의 64비트 정수로 표현되며, ns, us, ms 같은 다양한 단위를 가질 수 있어요.
  • Duration: Date/Datetime를 뺄 때 생성되는 시간 델타 타입. Python의 timedelta와 비슷해요.
  • Time: 시간 표현. 내부적으로는 자정 이후의 나노초로 표현됩니다.

파일에서 날짜 파싱 (Parsing dates from a file)

CSV 파일을 로드할 때 try_parse_dates 플래그가 True로 설정되어 있으면 Polars는 날짜와 시간을 파싱하려고 시도합니다:

import polars as pl

df = pl.read_csv("docs/assets/data/apple_stock.csv", try_parse_dates=True)
print(df)
shape: (100, 2)
┌──────────┬────────┐
│ Date     ┆ Close  │
│ ---      ┆ ---    │
│ date     ┆ f64    │
╞══════════╪════════╡
│ 1981-02-23 ┆ 24.62  │
│ 1981-05-06 ┆ 27.38  │
│ 1981-05-18 ┆ 28.0   │
│ 1981-09-25 ┆ 14.25  │
│ 1982-07-08 ┆ 11.0   │
│ …        ┆ …      │
│ 2012-05-16 ┆ 546.08 │
│ 2012-12-04 ┆ 575.85 │
│ 2013-07-05 ┆ 417.42 │
│ 2013-11-07 ┆ 512.49 │
│ 2014-02-25 ┆ 522.06 │
└──────────┴────────┘

이 플래그는 infer_schema_length 설정(기본값 100행)으로 구성된 행 수에 대해 스키마 추론을 트리거해요. 스키마 추론은 계산 비용이 커서, 많은 행을 사용하면 파일 로딩이 느려질 수 있습니다.

반면 parquet 같은 이진 형식은 Polars가 존중하는 스키마를 가지고 있어요.

문자열을 날짜로 캐스팅 (Casting strings to dates)

문자열로 인코딩된 datetime 칼럼을 datetime 타입으로 캐스팅할 수도 있어요. 문자열 str.to_date 메서드를 호출하면서 날짜 문자열의 형식을 전달하면 됩니다:

df = pl.read_csv("docs/assets/data/apple_stock.csv", try_parse_dates=False)

df = df.with_columns(pl.col("Date").str.to_date("%Y-%m-%d"))
print(df)

형식 문자열 사양은 여기에서 확인할 수 있어요.

날짜 칼럼에서 날짜 특성 추출 (Extracting date features from a date column)

.dt 네임스페이스를 사용하면 날짜 칼럼에서 연도나 일 같은 날짜 특성(feature)을 추출할 수 있습니다:

df_with_year = df.with_columns(pl.col("Date").dt.year().alias("year"))
print(df_with_year)

혼합 오프셋 (Mixed offsets)

데이터에 서로 다른 UTC 오프셋을 가진 datetime이 섞여 있다면(예: 일광 절약 시간 전환 때문에), Polars는 그것들을 UTC로 파싱해요. str.to_datetime에 대상 time_zone을 넘기거나, 파싱 후 str.convert_time_zone을 호출할 수 있습니다:

data = [
    "2021-03-27T00:00:00+0100",
    "2021-03-28T00:00:00+0100",
    "2021-03-29T00:00:00+0200",
    "2021-03-30T00:00:00+0200",
]
mixed_parsed = (
    pl.Series(data)
    .str.to_datetime("%Y-%m-%dT%H:%M:%S%z")
    .dt.convert_time_zone("Europe/Brussels")
)
print(mixed_parsed)

더 알아보기 (Learn more)