如何在Polars中为每个日期分配列表中的多个值?
问题描述
需要为DataFrame中的每个日期分配列表里的所有值,即每个日期对应列表中的每一个条目。直接将列表作为参数传入时,遇到了DataFrame长度不匹配的问题。
尝试的概念代码(报错)
from datetime import datetime import polars as pl Value_list = ["xd","xd1"] dates_df= pl.DataFrame( { "dates": pl.datetime_range( start=datetime(2023, 1, 1), end=datetime(2023, 12, 10), interval="1d", eager=True, closed="both", ), "Producto": Value_list } ) dates_df
当前实际代码(仅能添加单一值)
from datetime import datetime import polars as pl dates_df= pl.DataFrame( { "dates": pl.datetime_range( start=datetime(2023, 1, 1), end=datetime(2023, 12, 10), interval="1d", eager=True, closed="both", ), "Producto": "xd" } ) dates_df
期望输出
shape: (344, 2) ┌─────────────────────┬──────────┐ │ dates ┆ Producto │ │ --- ┆ --- │ │ datetime[μs] ┆ str │ ╞═════════════════════╪══════════╡ │ 2023-01-01 00:00:00 ┆ xd │ │ 2023-01-01 00:00:00 ┆ xd1 │ │ 2023-01-02 00:00:00 ┆ xd │ │ 2023-01-02 00:00:00 ┆ xd1 │ │ 2023-01-03 00:00:00 ┆ xd │ │ … ┆ … │ │ 2023-12-08 00:00:00 ┆ xd1 │ │ 2023-12-09 00:00:00 ┆ xd │ │ 2023-12-09 00:00:00 ┆ xd1 │ │ 2023-12-10 00:00:00 ┆ xd │ │ 2023-12-10 00:00:00 ┆ xd1 │ └─────────────────────┴──────────┘
解决方案
要实现每个日期与列表中所有值的配对,本质是生成日期列和Producto列的笛卡尔积,在Polars中可以通过以下两种方式实现:
方法一:交叉连接(cross_join)
先分别创建日期和Producto的DataFrame,再执行交叉连接生成笛卡尔积:
from datetime import datetime import polars as pl Value_list = ["xd", "xd1"] # 生成日期DataFrame dates_df = pl.DataFrame( { "dates": pl.datetime_range( start=datetime(2023, 1, 1), end=datetime(2023, 12, 10), interval="1d", eager=True, closed="both", ) } ) # 生成Producto的DataFrame product_df = pl.DataFrame({"Producto": Value_list}) # 执行交叉连接 result_df = dates_df.cross_join(product_df) print(result_df)
方法二:重复+展开(repeat + explode)
通过重复Producto列表对应日期的行数,再展开列实现配对:
from datetime import datetime import polars as pl Value_list = ["xd", "xd1"] dates_df = pl.DataFrame( { "dates": pl.datetime_range( start=datetime(2023, 1, 1), end=datetime(2023, 12, 10), interval="1d", eager=True, closed="both", ) } ) # 重复Producto列表,次数等于日期行数,再展开 result_df = dates_df.with_columns( Producto=pl.lit(Value_list).repeat(pl.count()).explode() ) print(result_df)
说明
两种方法都能生成符合期望的输出,解决了直接传入列表时的长度不匹配问题:
cross_join逻辑直观,适合需要明确笛卡尔积操作的场景;repeat+explode通过列级操作实现,代码更紧凑。
内容的提问来源于stack exchange,提问作者user24900119
相关产品推荐
相关产品推荐

