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,
将类型为
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}}]