Created at : 2024-09-06 12:51
Auther: Soo.Y

2. 기본 데이터 구조

Polars에서 데이터를 다루기 위해 사용하는 기본적인 데이터 구조는 DataFrameSeries입니다. 이 장에서는 Polars의 두 가지 핵심 데이터 구조인 DataFrameSeries에 대해 다루고, 이를 생성하고 조작하는 방법을 배웁니다.


2.1 DataFrame이란?

Polars의 DataFrame은 테이블 형식의 데이터를 저장하고 처리하는 데이터 구조로, Pandas의 DataFrame과 유사한 방식으로 동작합니다. 각 열은 동일한 데이터 타입을 가지며, 열과 행을 기준으로 데이터를 조회하고 조작할 수 있습니다.

2.2 Series란?

Series는 Polars에서 단일 열(1D 배열)을 나타내는 데이터 구조입니다. DataFrame은 여러 개의 Series를 모아놓은 구조라고 생각할 수 있습니다. 각 Series는 하나의 데이터 타입을 가지며, 연산을 통해 데이터를 쉽게 조작할 수 있습니다.


2.3 데이터프레임 생성하기

Polars에서 DataFrame을 생성하는 방법에는 여러 가지가 있습니다. 대표적으로 딕셔너리, 리스트, 그리고 CSV 파일 등 외부 파일을 이용해 생성할 수 있습니다.

2.3.1 딕셔너리로 DataFrame 생성하기

import polars as pl
 
# 딕셔너리를 이용한 DataFrame 생성
df = pl.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "city": ["New York", "Los Angeles", "Chicago"]
})
 
# DataFrame 출력
print(df)

위 코드에서 pl.DataFrame()에 딕셔너리를 전달하여 각 키가 열의 이름이 되고, 값이 해당 열의 데이터가 되는 DataFrame을 생성합니다.

2.3.2 리스트로 DataFrame 생성하기

리스트로 DataFrame을 생성할 때는 열 이름을 따로 지정해야 합니다.

# 리스트를 이용한 DataFrame 생성
df = pl.DataFrame(
    [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
    schema=["col1", "col2", "col3"]
)
 
# DataFrame 출력
print(df)

여기서 schema 매개변수를 사용해 열 이름을 지정할 수 있습니다.

2.3.3 CSV 파일로 DataFrame 생성하기

Polars는 다양한 파일 형식으로부터 데이터를 읽어와 DataFrame을 생성할 수 있습니다. 그 중 하나가 CSV 파일입니다.

# CSV 파일에서 DataFrame 생성
df = pl.read_csv("data.csv")
 
# 데이터 출력
print(df)

이 코드에서는 pl.read_csv()를 이용해 CSV 파일을 읽어와 DataFrame으로 변환합니다.


2.4 Series 객체 다루기

Series는 Polars에서 단일 열을 나타내며, Pandas의 Series와 비슷하게 동작합니다. Polars의 Series는 다양한 기본 연산 및 함수를 지원합니다.

2.4.1 Series 생성하기

# Series 생성
s = pl.Series("age", [25, 30, 35])
 
# Series 출력
print(s)

pl.Series() 함수는 Series 객체를 생성하며, 첫 번째 인수는 열 이름, 두 번째 인수는 데이터 리스트입니다.

2.4.2 Series 기본 연산

Polars의 Series는 기본적인 수학 연산을 지원합니다.

# Series 기본 연산
s = pl.Series([10, 20, 30])
 
# 모든 값에 2를 더하기
s_plus_2 = s + 2
print(s_plus_2)
 
# 모든 값에 5를 곱하기
s_times_5 = s * 5
print(s_times_5)

이 코드는 Series의 모든 값에 대해 각각 더하기와 곱하기 연산을 수행하는 예시입니다.


2.5 데이터프레임 탐색

데이터프레임의 구조와 내용을 탐색하는 다양한 방법이 있습니다.

2.5.1 데이터 미리보기

Polars에서 데이터의 구조를 살펴보는 기본적인 함수들입니다.

  • head(): 데이터프레임의 상위 몇 개의 행을 출력합니다.
  • tail(): 데이터프레임의 하위 몇 개의 행을 출력합니다.
  • shape(): 데이터프레임의 행과 열의 개수를 반환합니다.
  • columns(): 데이터프레임의 열 이름을 반환합니다.
df = pl.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "city": ["New York", "Los Angeles", "Chicago"]
})
 
# 상위 2개 행 출력
print(df.head(2))
 
# 행과 열의 개수 출력
print(df.shape)
 
# 열 이름 출력
print(df.columns)

2.5.2 데이터 선택하기

Polars에서는 특정 열이나 행을 선택할 수 있는 다양한 방법을 제공합니다.

열 선택하기 (select())

# 'name' 열 선택하기
name_col = df.select("name")
print(name_col)

select()는 특정 열을 선택하여 반환합니다. 여러 개의 열을 선택하고 싶다면 리스트로 열 이름을 전달할 수 있습니다.

조건부 선택 (filter())

조건에 맞는 행을 선택하려면 filter()를 사용합니다.

# 나이가 30 이상인 행 선택
age_filtered = df.filter(pl.col("age") >= 30)
print(age_filtered)

위 코드는 “age” 열에서 값이 30 이상인 행만 선택하여 반환합니다.


2.6 데이터프레임 연산

Polars는 데이터프레임에서 여러 연산을 빠르고 효율적으로 수행할 수 있도록 다양한 메서드를 제공합니다.

2.6.1 열 추가 및 수정

데이터프레임에 새로운 열을 추가하거나 기존 열을 수정할 수 있습니다.

# 새로운 열 추가
df = df.with_columns([
    (pl.col("age") + 5).alias("age_plus_5")
])
 
print(df)

위 코드에서 with_columns()는 기존 데이터프레임에 새 열을 추가하며, alias()를 사용해 열 이름을 지정합니다.

2.6.2 열 삭제

Polars에서 특정 열을 삭제하려면 drop()을 사용할 수 있습니다.

# 'city' 열 삭제
df = df.drop("city")
print(df)

drop() 함수는 지정한 열을 데이터프레임에서 삭제합니다.


행의 추가, 수정, 삭제는 데이터프레임을 다룰 때 중요한 작업 중 하나입니다. Polars에서는 이를 효율적으로 처리할 수 있는 여러 가지 방법을 제공합니다. 아래에서는 행을 추가하고 수정하거나 삭제하는 방법을 구체적으로 설명하겠습니다.


2.6.3 행 추가 및 수정

Polars는 DataFrame에 행을 추가하거나 수정할 때 새로운 DataFrame을 생성하는 방식으로 작동합니다. 즉, 데이터프레임 자체는 불변(immutable)이고, 기존의 데이터를 수정하거나 새로운 행을 추가하는 대신 변경된 데이터를 포함한 새로운 데이터프레임을 반환합니다.

새로운 행 추가하기

Polars는 기존의 데이터프레임에 행을 추가할 수 있도록 `vstack()` 메서드를 제공합니다. 새로운 행을 추가하려면 다른 DataFrame을 결합해야 합니다.
import polars as pl
 
# 기존 DataFrame
df = pl.DataFrame({
    "name": ["Alice", "Bob"],
    "age": [25, 30],
    "city": ["New York", "Los Angeles"]
})
 
# 추가할 행을 새로운 DataFrame으로 정의
new_row = pl.DataFrame({
    "name": ["Charlie"],
    "age": [35],
    "city": ["Chicago"]
})
 
# 행 추가 (두 데이터프레임 결합)
df = df.vstack(new_row)
 
print(df)

여기서 vstack() 함수는 두 데이터프레임을 수직으로 쌓아 새로운 행을 추가합니다. 추가할 데이터를 DataFrame으로 만든 후 결합하는 방식으로 행을 추가할 수 있습니다.

행 수정하기

Polars에서는 기존 데이터를 수정하는 대신, 조건을 적용해 새로운 데이터를 생성하는 방식으로 작업합니다. 예를 들어 특정 조건을 만족하는 행의 값을 수정하려면 with_columns()와 조건식을 사용하여 새롭게 값을 할당할 수 있습니다.

# 'name'이 'Bob'인 행의 'age' 값을 40으로 수정
df = df.with_columns(
    pl.when(pl.col("name") == "Bob").then(40).otherwise(pl.col("age")).alias("age")
)
 
print(df)

위 예제에서 pl.when()pl.otherwise()를 사용하여 “name”이 “Bob”인 행의 “age” 값을 40으로 수정하고, 그 외의 값은 기존 값을 유지합니다. 이 방식은 행을 수정할 때 매우 유용합니다.


2.6.4 행 삭제

Polars에서 특정 행을 삭제하려면 조건을 사용하여 데이터를 필터링하는 방식으로 행을 제거할 수 있습니다. 이때 filter()를 사용하여 조건에 맞지 않는 행을 필터링할 수 있습니다.

특정 조건에 맞는 행 삭제하기

예를 들어, 특정 조건을 만족하는 행을 삭제하고 싶을 때는 다음과 같이 filter()를 사용할 수 있습니다.

# 'age'가 30 이상인 행만 남기고 나머지 행 삭제
df = df.filter(pl.col("age") >= 30)
 
print(df)

위 예제에서 filter()는 “age” 열의 값이 30 이상인 행만 남기고, 나머지 행을 삭제하는 방식으로 작동합니다.

인덱스를 사용해 행 삭제하기

Polars는 직접적으로 특정 인덱스를 기반으로 행을 삭제하는 기능은 없지만, 삭제하고자 하는 인덱스를 제외한 나머지 행을 필터링하는 방식으로 행을 삭제할 수 있습니다.

# 첫 번째 행 (인덱스 0) 삭제
df = df.drop_in_place_at_idx(0)
 
print(df)

drop_in_place_at_idx()를 사용하면 특정 인덱스 위치에 있는 행을 삭제할 수 있습니다.


2.7 마무리

이 장에서는 Polars의 두 가지 핵심 데이터 구조인 DataFrameSeries의 생성과 기본적인 조작 방법에 대해 다뤘습니다. Polars의 간단한 API를 통해 데이터를 효율적으로 관리하고 탐색할 수 있는 방법을 배웠습니다.

다음 장에서는 이 기본적인 기능을 바탕으로, 데이터를 더 깊이 분석하고 변형하는 방법을 살펴보겠습니다.

관련 문서

1. Polars 소개