在 Polars LazyFrame 上使用 pl.struct 时,在不同列上迭代应用 with_columns 时出现 KeyError

J. *_*rez 2 python dataframe keyerror python-polars lazyframe

我对 with_columns 中的 Polars LazyFrame“Structs”(pl.struct)和“apply”(又名 map_elements)有以下问题

这里的想法是尝试将自定义逻辑应用于属于多个列的一组值

我已经能够使用 DataFrames 实现这一点;但是,当切换到 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)
Run Code Online (Sandbox Code Playgroud)
  • 损坏的 LazyFrame 实现
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())
Run Code Online (Sandbox Code Playgroud)

(啊,是的,请注意,单独执行每个迭代确实有效,所以对我来说,为什么 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")
)
Run Code Online (Sandbox Code Playgroud)

我找到了一种使用 pl.col 来实现我想要的结果的解决方法,但我想知道 Structs 是否可以像我使用 DataFrames 一样与 LazyFrames 一起使用,或者它实际上是这个 Polars 版本中的一个错误

顺便说一句,我正在使用 Polars 0.19.13。感谢您的关注

jqu*_*ous 5

这更像是 Python 本身的一般“陷阱”:官方 Python 常见问题解答

\n

它会崩溃,因为col每个结果都具有相同的值lambda

\n

一种方法是使用命名/关键字参数:

\n
lambda row, col=col: validate_stuff(row[col], row["notes"])\n
Run Code Online (Sandbox Code Playgroud)\n
shape: (4, 3)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 foo \xe2\x94\x86 bar \xe2\x94\x86 notes                             \xe2\x94\x82\n\xe2\x94\x82 --- \xe2\x94\x86 --- \xe2\x94\x86 ---                               \xe2\x94\x82\n\xe2\x94\x82 str \xe2\x94\x86 str \xe2\x94\x86 str                               \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 a   \xe2\x94\x86 w   \xe2\x94\x86 FAILED w - PREVIOUS (1)           \xe2\x94\x82\n\xe2\x94\x82 b   \xe2\x94\x86 x   \xe2\x94\x86 2                                 \xe2\x94\x82\n\xe2\x94\x82 c   \xe2\x94\x86 y   \xe2\x94\x86 FAILED y - PREVIOUS (FAILED c - \xe2\x80\xa6 \xe2\x94\x82\n\xe2\x94\x82 d   \xe2\x94\x86 z   \xe2\x94\x86 FAILED z - PREVIOUS (FAILED d - \xe2\x80\xa6 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n