给定如下所示的 Polars df,如何在两列上调用
explode()
,同时将空条目扩展到正确的长度以与其行匹配?
shape: (3, 2)
┌───────────┬─────────────────────┐
│ x ┆ y │
│ --- ┆ --- │
│ list[i64] ┆ list[bool] │
╞═══════════╪═════════════════════╡
│ [1] ┆ [true] │
│ [1, 2] ┆ null │
│ [1, 2, 3] ┆ [true, false, true] │
└───────────┴─────────────────────┘
当前调用 df.explode(["x", "y" ]) 将导致此错误:
polars.exceptions.ShapeError: exploded columns must have matching element counts
我假设没有内置方式。但我找不到/想不出一种方法将该空值转换为具有正确长度的列表,以便爆炸可以工作(假设我事先不静态地知道所需的长度)。
我研究了传递列表。长度写入repeat_by(),但repeat_by()不支持null。
没有内置的方法来使用
explode
处理 Polars 中不等长的列表。但是,可以使用以下方法预处理数据帧:
import polars as pl
df = pl.DataFrame({
"x": [[1], [1, 2], [1, 2, 3]],
"y": [[True], None, [True, False, True]]
})
def explode_fill(df, columns):
# Find the maximum length of lists in the specified columns
max_len = df.select(pl.max([pl.col(c).arr.len() for c in columns])).item()
# Fill null values and extend lists to the maximum length
for col in columns:
df = df.with_columns(
pl.when(pl.col(col).is_null())
.then(pl.lit(pl.repeat(None, max_len).alias(col)))
.otherwise(pl.col(col))
)
return df.explode(columns)
df = explode_fill(df, ["x", "y"])
print(df)
此代码执行以下操作:
-
explode_fill
函数: - 接受数据帧和要展开的列列表作为输入。
-
计算指定列中列表的最大长度 (
max_len
)。 -
迭代要展开的列:
-
使用
pl.when
检查空值 (None
)。 -
如果为
None
,则使用pl.repeat(None, max_len)
将其替换为具有max_len
个None
值的列表。 - 否则,保持原始值。
-
使用
-
使用
explode
展开修改后的列。 -
应用
explode_fill
函数: -
在数据帧和列
["x", "y"]
上调用explode_fill
函数。
此代码有效地将空列表或
None
值替换为具有正确长度(由最长列表确定)的
None
值列表,从而允许
explode
在没有错误的情况下工作。
此解决方案避免了使用
apply
或
map
,这在处理更大的数据集时可以提高性能。