连接
有几种方法可以从不同的DataFrames中连接数据:
- 两个具有相同列的数据框可以垂直连接以形成一个更长的数据框
- 两个具有非重叠列的数据框可以水平连接以形成一个更宽的数据框
- 两个具有不同行数和列数的数据框可以对角连接,以生成一个可能更长和/或更宽的数据框。在列名重叠的地方,值将垂直连接。在列名不重叠的地方,将添加新的行和列。缺失值将设置为
null
垂直连接 - 变得更长
在垂直连接中,您将来自DataFrames列表的所有行组合成一个更长的DataFrame。
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)
let df_v1 = df!(
"a"=> &[1],
"b"=> &[3],
)?;
let df_v2 = df!(
"a"=> &[2],
"b"=> &[4],
)?;
let df_vertical_concat = concat(
[df_v1.clone().lazy(), df_v2.clone().lazy()],
UnionArgs::default(),
)?
.collect()?;
println!("{}", &df_vertical_concat);
shape: (2, 2)
┌─────┬─────┐
│ a ┆ b │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 1 ┆ 3 │
│ 2 ┆ 4 │
└─────┴─────┘
当数据框的列名不相同时,垂直连接会失败。
水平连接 - 变得更宽
在水平连接中,您将来自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)
let df_h1 = df!(
"l1"=> &[1, 2],
"l2"=> &[3, 4],
)?;
let df_h2 = df!(
"r1"=> &[5, 6],
"r2"=> &[7, 8],
"r3"=> &[9, 10],
)?;
let df_horizontal_concat = polars::functions::concat_df_horizontal(&[df_h1, df_h2], true)?;
println!("{}", &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 │
└─────┴─────┴─────┴─────┴─────┘
当数据框有重叠列时,水平连接会失败。
当数据框具有不同数量的行时,列将在末尾填充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",
)
print(df_horizontal_concat)
let df_h1 = df!(
"l1"=> &[1, 2],
"l2"=> &[3, 4],
)?;
let df_h2 = df!(
"r1"=> &[5, 6, 7],
"r2"=> &[8, 9, 10],
)?;
let df_horizontal_concat = polars::functions::concat_df_horizontal(&[df_h1, df_h2], true)?;
println!("{}", &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 │
└──────┴──────┴─────┴─────┘
对角线连接 - 变得更长、更宽和更null
在对角连接中,您将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)
let df_d1 = df!(
"a"=> &[1],
"b"=> &[3],
)?;
let df_d2 = df!(
"a"=> &[2],
"d"=> &[4],)?;
let df_diagonal_concat = polars::functions::concat_df_diagonal(&[df_d1, df_d2])?;
println!("{}", &df_diagonal_concat);
shape: (2, 3)
┌─────┬──────┬──────┐
│ a ┆ b ┆ d │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 │
╞═════╪══════╪══════╡
│ 1 ┆ 3 ┆ null │
│ 2 ┆ null ┆ 4 │
└─────┴──────┴──────┘
当列名不重叠时,对角线连接会生成空值。
当数据框的形状不匹配并且我们有一个重叠的语义键时, 我们可以连接数据框而不是将它们串联起来。
重新分块
在连接之前,我们有两个数据框 df1 和 df2。df1 和 df2 中的每一列在内存中都有一个或多个块。默认情况下,在连接过程中,每列中的块不会连续排列。这使得连接操作更快且消耗更少的内存,但可能会减慢未来从数据连续内存中受益的操作。将分散的块复制到一个新块中的过程称为 重新分块。重新分块是一个昂贵的操作。在版本 0.20.26 之前,默认是执行重新分块,但在新版本中,默认是不执行。如果你确实希望 Polars 对连接的 DataFrame 进行重新分块,你可以在连接时指定 rechunk = True。