polars.Expr.list.to_struct#

Expr.list.to_struct(
n_field_strategy: ListToStructWidthStrategy = 'first_non_null',
fields: Sequence[str] | Callable[[int], str] | None = None,
upper_bound: int = 0,
*,
_eager: bool = False,
) Expr[source]#

将类型为 List 的 Series 转换为类型为 Struct 的 Series。

Parameters:
n_field_strategy{‘first_non_null’, ‘max_width’}

确定结构体字段数量的策略。

  • “first_non_null”:设置字段数量等于第一个非零长度子列表的长度。

  • “max_width”:将所有子列表的最大长度设置为字段数量。

fields

如果预先知道所需字段的名称和数量,可以提供一个字段名称列表,这些字段将按索引分配。否则,可以使用自定义函数动态分配字段名称;如果两者都未设置,字段将命名为field_0, field_1 .. field_n

upper_bound

一个polars的LazyFrame需要始终知道模式,因此调用者必须提供一个将被创建的结构字段数量的上限;如果设置不正确,后续操作可能会失败。(例如,一个all().sum()表达式将查看当前模式以确定选择哪些列)。

在对DataFrame进行操作时,不需要跟踪或预先确定模式,因为结果将被急切评估,因此您可以不设置此参数。

注释

建议将‘upper_bound’设置为结构的正确输出大小。 如果未设置此值,Polars将不知道此操作的输出类型, 并将其设置为‘Unknown’,这可能会导致错误,因为Polars无法解析查询。

出于性能考虑,使用第一个非空子列表的长度来确定输出字段的数量。如果子列表的长度可能不同,则必须使用n_field_strategy="max_width"以获得预期的结果。

示例

将列表转换为结构体,使用默认字段名称分配:

>>> df = pl.DataFrame({"n": [[0, 1], [0, 1, 2]]})
>>> df.with_columns(struct=pl.col("n").list.to_struct())  
shape: (2, 2)
┌───────────┬───────────┐
│ n         ┆ struct    │
│ ---       ┆ ---       │
│ list[i64] ┆ struct[2] │ # <- struct with 2 fields
╞═══════════╪═══════════╡
│ [0, 1]    ┆ {0,1}     │ # OK
│ [0, 1, 2] ┆ {0,1}     │ # NOT OK - last value missing
└───────────┴───────────┘

由于较短的子列表先出现,我们必须使用max_width策略来强制搜索最长的。

>>> df.with_columns(
...     struct=pl.col("n").list.to_struct(n_field_strategy="max_width")
... )  
shape: (2, 2)
┌───────────┬────────────┐
│ n         ┆ struct     │
│ ---       ┆ ---        │
│ list[i64] ┆ struct[3]  │ # <- struct with 3 fields
╞═══════════╪════════════╡
│ [0, 1]    ┆ {0,1,null} │ # OK
│ [0, 1, 2] ┆ {0,1,2}    │ # OK
└───────────┴────────────┘

通过函数/索引将列表转换为带有字段名称分配的结构体:

>>> df = pl.DataFrame({"n": [[0, 1], [2, 3]]})
>>> df.select(pl.col("n").list.to_struct(fields=lambda idx: f"n{idx}")).rows(
...     named=True
... )  
[{'n': {'n0': 0, 'n1': 1}}, {'n': {'n0': 2, 'n1': 3}}]

通过从名称列表中按索引分配字段名称,将列表转换为结构体:

>>> df.select(pl.col("n").list.to_struct(fields=["one", "two"])).rows(
...     named=True
... )
[{'n': {'one': 0, 'two': 1}}, {'n': {'one': 2, 'two': 3}}]