연결
연결 (Concatenation)
여러 개의 데이터프레임을 이어 붙이는 방법은 상황에 따라 여러 가지가 있어요. 칼럼이 같은 데이터프레임 두 개는 세로로 붙여 더 긴 데이터프레임을 만들고, 칼럼이 겹치지 않는 두 개는 가로로 붙여 더 넓은 데이터프레임을 만들죠. 이 섹션에서는 Polars의 concat가 제공하는 세 가지 방향 — 세로, 가로, 대각선 — 을 차례로 살펴볼게요.
출처: 공식문서
세로 연결 (Vertical concatenation) - 더 길어지기
세로 연결(vertical concatenation)은 DataFrames 리스트의 모든 행을 하나의 더 긴 DataFrame으로 결합해요.
import polars as pl
df_v1 = pl.DataFrame(
{
"a": [1],
"b": [3],
}
)
df_v2 = pl.DataFrame(
{
"a": [2],
"b": [4],
}
)
df_vertical_concat = pl.concat(
[
df_v1,
df_v2,
],
how="vertical",
)
print(df_vertical_concat)
shape: (2, 2)
┌─────┬─────┐
│ a ┆ b │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 1 ┆ 3 │
│ 2 ┆ 4 │
└─────┴─────┘
세로 연결은 데이터프레임들이 같은 칼럼 이름을 가지지 않으면 실패합니다.
가로 연결 (Horizontal concatenation) - 더 넓어지기
가로 연결(horizontal concatenation)은 DataFrames 리스트의 모든 칼럼을 하나의 더 넓은 DataFrame으로 결합해요.
df_h1 = pl.DataFrame(
{
"l1": [1, 2],
"l2": [3, 4],
}
)
df_h2 = pl.DataFrame(
{
"r1": [5, 6],
"r2": [7, 8],
"r3": [9, 10],
}
)
df_horizontal_concat = pl.concat(
[
df_h1,
df_h2,
],
how="horizontal",
)
print(df_horizontal_concat)
shape: (2, 5)
┌─────┬─────┬─────┬─────┬─────┐
│ l1 ┆ l2 ┆ r1 ┆ r2 ┆ r3 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╪═════╪═════╡
│ 1 ┆ 3 ┆ 5 ┆ 7 ┆ 9 │
│ 2 ┆ 4 ┆ 6 ┆ 8 ┆ 10 │
└─────┴─────┴─────┴─────┴─────┘
가로 연결은 데이터프레임들이 겹치는 칼럼을 가지면 실패하고, 또 두 데이터프레임의 높이(행 수)가 같아야 합니다. 높이가 다른 데이터프레임을 결합하려면 how="horizontal_extend"를 쓰세요. 이 모드는 더 짧은 칼럼의 끝을 null 값으로 채워서 가장 긴 데이터프레임의 높이에 맞춥니다.
df_h1 = pl.DataFrame(
{
"l1": [1, 2],
"l2": [3, 4],
}
)
df_h2 = pl.DataFrame(
{
"r1": [5, 6, 7],
"r2": [8, 9, 10],
}
)
df_horizontal_concat = pl.concat(
[
df_h1,
df_h2,
],
how="horizontal_extend",
)
print(df_horizontal_concat)
shape: (3, 4)
┌──────┬──────┬─────┬─────┐
│ l1 ┆ l2 ┆ r1 ┆ r2 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪═════╪═════╡
│ 1 ┆ 3 ┆ 5 ┆ 8 │
│ 2 ┆ 4 ┆ 6 ┆ 9 │
│ null ┆ null ┆ 7 ┆ 10 │
└──────┴──────┴─────┴─────┘
대각선 연결 (Diagonal concatenation) - 더 길어지고, 더 넓어지고, 더 null 많아지기
대각선 연결(diagonal concatenation)은 DataFrames 리스트의 모든 행과 칼럼을 하나의 더 길고/더 넓은 DataFrame으로 결합해요.
df_d1 = pl.DataFrame(
{
"a": [1],
"b": [3],
}
)
df_d2 = pl.DataFrame(
{
"a": [2],
"d": [4],
}
)
df_diagonal_concat = pl.concat(
[
df_d1,
df_d2,
],
how="diagonal",
)
print(df_diagonal_concat)
shape: (2, 3)
┌─────┬──────┬──────┐
│ a ┆ b ┆ d │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 │
╞═════╪══════╪══════╡
│ 1 ┆ 3 ┆ null │
│ 2 ┆ null ┆ 4 │
└─────┴──────┴──────┘
대각선 연결은 칼럼 이름이 겹치지 않을 때 null을 생성합니다.
데이터프레임의 형태가 맞지 않으면서 겹치는 의미적 키(semantic key)가 있다면, 연결 대신 데이터프레임을 조인할 수 있어요.
리청킹 (Rechunking)
연결 전에 우리에겐 df1과 df2 두 데이터프레임이 있어요. df1과 df2의 각 칼럼은 메모리에서 하나 이상의 청크(chunk)에 들어 있죠. 기본적으로 연결 중에는 각 칼럼의 청크들이 연속되게(contiguous) 만들어지지 않습니다. 이렇게 하면 연결 연산이 더 빠르고 메모리를 덜 쓰지만, 데이터가 연속 메모리에 있을 때 이점을 얻는 이후 연산은 느려질 수 있어요. 분산된(fragmented) 청크들을 하나의 새 청크로 복사하는 과정을 **리청킹(rechunking)**이라고 합니다. 리청킹은 비용이 큰 연산이에요. 버전 0.20.26 이전에는 리청킹이 기본이었지만, 새 버전에서는 기본적으로 수행하지 않습니다. 연결된 DataFrame을 Polars가 리청킹하길 원한다면 연결 시 rechunk = True를 지정하세요.
더 알아보기 (Learn more)
- 데이터프레임을 행·칼럼 기준으로 접합하는 대신 키 값을 기준으로 결합하고 싶다면 조인 문서를 참고하세요.