#Struct #구조체 #vs.Pandas
간단한 DataFrame 을 만들고 그 안에서
기존 컬럼들을 조합해서 Dict 타입의 새로운 컬럼을 생성해보자.
- struct 키워드를 알아야 한다.
- with_columns 함수를 사용한다.
- pandas 문법과 성능을 비교한다.
아래와 같은 데이터셋을 생성한다.
%%time
import polars as pl
pl.Config(fmt_table_cell_list_len=10)
gt = 1000000
df = pl.DataFrame({
'A': [i for i in range(gt)],
'B': [str(i)+'_STR' for i in range(gt)],
'C': [bool(i) for i in range(gt)],
'D': [i * 10 for i in range(gt)]
})
이제 A, B, C 를 사용해서 Dict 형태의 구조체를 만들어 보자.
%%time
df = df.with_columns([
pl.struct(['A', 'B', 'C']).alias('abc_struct'),
pl.struct(['B', 'C', 'D']).alias('bcd_struct')
])
df
어렵지 않게 구조체 데이터를 생성할 수 있다.
여기서,
abc_struct 의 값에 접근해서 값을 변경 할 수 있을까?
아직 그런 함수는 찾지 못했다.
하지만!
다른 방식으로 접근한다면 가능하다.
변경하고자 하는 key 값의 데이터를 변경하고 새로운 컬럼으로 추가한다.
그리고 다시 다른 값들과 조합해서 struct 를 생성한다.
%%time
df = df.with_columns([
(pl.col('abc_struct').struct.field('A') ** 2).alias('tmp_modified_a_field')
]).with_columns([
pl.struct(['tmp_modified_a_field', 'B', 'C']).alias('abc_struct')
]).drop(['tmp_modified_a_field'])
이걸 pandas 에서 돌려보았는데
시간이 너무 오래 걸려서 그만 두었다.
즉, 성능 비교 자체가 어렵다!
polars 에서도 apply, lambda, map 등을 사용하면 pandas 처럼 느려진다.
최대한 functional API 를 잘 조합해서 로직을 만드는게 최우선이다.
도저히 만들 수 없을 때
Rust 를 살짝 배워서 원하는 로직을 UDF 로 만들고
Python 에서 import 해서 polars 와 함께 사용하면 될 것이다.