设置如下:
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 为结构体的惯用方式是什么?
文档判断,您不应该将字典传递到结构构造函数中。只需将每个
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