如何在“eval”处理“列表”时创建“结构”?

问题描述 投票:0回答:1

设置如下:

import polars as pl

df = pl.DataFrame(
    [
        pl.Series("start", ["2023-01-01"], dtype=pl.Date).str.to_date(),
        pl.Series("end", ["2024-01-01"], dtype=pl.Date).str.to_date(),
    ]
)
shape: (1, 2)
┌────────────┬────────────┐
│ start      ┆ end        │
│ ---        ┆ ---        │
│ date       ┆ date       │
╞════════════╪════════════╡
│ 2023-01-01 ┆ 2024-01-01 │
└────────────┴────────────┘
df = df.with_columns(
    pl.date_range(pl.col("start"), pl.col("end"), "1mo", closed="left")
    .implode()
    .alias("date_range")
)
shape: (1, 3)
┌────────────┬────────────┬─────────────────────────────────┐
│ start      ┆ end        ┆ date_range                      │
│ ---        ┆ ---        ┆ ---                             │
│ date       ┆ date       ┆ list[date]                      │
╞════════════╪════════════╪═════════════════════════════════╡
│ 2023-01-01 ┆ 2024-01-01 ┆ [2023-01-01, 2023-02-01, … 202… │
└────────────┴────────────┴─────────────────────────────────┘

现在我想用年/月部分创建一个结构:

df = df.with_columns(
    pl.col("date_range")
    .list.eval(
        pl.struct(
            {
                "year": pl.element().dt.year(),
                "month": pl.element().dt.month(),
            }
        )
    )
    .alias("years_months")
)

但这不起作用。也许我不应该将

implode
的输出放入列表中,但我也不知道如何直接从其结果创建结构......
我最好的想法是我不喜欢的,因为我必须重复

date_range

pl.list.eval...

另一个想法是使用
df = ( df.with_columns( pl.col("date_range").list.eval(pl.element().dt.year()).alias("year"), pl.col("date_range").list.eval(pl.element().dt.month()).alias("month"), ) .drop("start", "end", "date_range") .explode("year", "month") .select(pl.struct("year", "month")) ) df

,但我认为这应该是最后的手段? eval 为结构体的惯用方式是什么?

    

python python-polars
1个回答
0
投票

map_elements

 文档判断,您不应该将字典传递到结构构造函数中。只需将每个 
polars.struct 作为关键字参数传递 - 即
IntoExpr
在您的情况下,您可以将结构代码替换为以下内容:

pl.struct(key1=IntoExprA, key2=IntoExprB, ...)

打印
df = df.with_columns( pl.col("date_range") .list.eval( pl.struct( year = pl.element().dt.year(), month = pl.element().dt.month() ) ) .alias("years_months") )

给了我这个输出:

df

	
© www.soinside.com 2019 - 2024. All rights reserved.