我在 with_columns 中使用 Polars 的 LazyFrame“Structs”(pl.struct) 和“apply”(又名 map_elements)时遇到以下问题
这里的想法是尝试将自定义逻辑应用于属于多个列的一组值
我已经能够使用 DataFrame 实现这一目标;但是,当切换到 LazyFrames 时,每当我尝试访问由结构发送到函数的字典中的列时,就会引发 KeyError。我逐一循环列,以便应用不同的函数(在其他地方映射到它们的名称,但在下面的示例中,为了简单起见,我将仅使用相同的函数)
my_df = pl.DataFrame(
{
"foo": ["a", "b", "c", "d"],
"bar": ["w", "x", "y", "z"],
"notes": ["1", "2", "3", "4"]
}
)
print(my_df)
cols_to_validate = ("foo", "bar")
def validate_stuff(value, notes):
# Any custom logic
if value not in ["a", "b", "x"]:
return f"FAILED {value} - PREVIOUS ({notes})"
else:
return notes
for col in cols_to_validate:
my_df = my_df.with_columns(
pl.struct([col, "notes"]).map_elements(
lambda row: validate_stuff(row[col], row["notes"])
).alias("notes")
)
print(my_df)
my_lf = pl.DataFrame(
{
"foo": ["a", "b", "c", "d"],
"bar": ["w", "x", "y", "z"],
"notes": ["1", "2", "3", "4"]
}
).lazy()
def validate_stuff(value, notes):
# Any custom logic
if value not in ["a", "b", "x"]:
return f"FAILED {value} - PREVIOUS ({notes})"
else:
return notes
cols_to_validate = ("foo", "bar")
for col in cols_to_validate:
my_lf = my_lf.with_columns(
pl.struct([col, "notes"]).map_elements(
lambda row: validate_stuff(row[col], row["notes"])
).alias("notes")
)
print(my_lf.collect())
(啊,是的,请注意,单独执行每个迭代确实有效,所以对于我来说 for 循环中断的原因没有任何意义)
my_lf = my_lf.with_columns(
pl.struct(["foo", "notes"]).map_elements(
lambda row: validate_stuff(row["foo"], row["notes"])
).alias("notes")
)
my_lf = my_lf.with_columns(
pl.struct(["bar", "notes"]).map_elements(
lambda row: validate_stuff(row["bar"], row["notes"])
).alias("notes")
)
我找到了一种使用 pl.col 来实现我想要的结果的解决方法,但我想知道 Structs 是否可以像我使用 DataFrames 一样与 LazyFrames 一起使用,或者它实际上是这个 Polars 版本中的一个错误
顺便说一句,我正在使用 Polars 0.19.13。谢谢您的关注
这更像是 Python 本身的一般“陷阱”:官方 Python 常见问题解答
它会崩溃,因为
col
最终每个 lambda
都有相同的值
一种方法是使用命名/关键字参数:
lambda row, col=col: validate_stuff(row[col], row["notes"])
shape: (4, 3)
┌─────┬─────┬───────────────────────────────────┐
│ foo ┆ bar ┆ notes │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞═════╪═════╪═══════════════════════════════════╡
│ a ┆ w ┆ FAILED w - PREVIOUS (1) │
│ b ┆ x ┆ 2 │
│ c ┆ y ┆ FAILED y - PREVIOUS (FAILED c - … │
│ d ┆ z ┆ FAILED z - PREVIOUS (FAILED d - … │
└─────┴─────┴───────────────────────────────────┘