PHP前端开发

如何基于其他 DataFrame 行过滤器创建列?

百变鹏仔 1天前 #Python
文章标签 过滤器
问题内容

我有一个名为“hourly_data”的 lazyframe,其中包含一个名为“time”的每小时日期时间列。我还有一个名为“future_periods”的 dataframe,其中包含两个日期时间列,称为“start”(未来周期的开始日期时间)和“end”(未来周期的结束时间)。重要的是,这些未来时期并不重叠。

我想为 hourly_data lazyframe 创建一个名为“period”的列,它应该有一个 int 值,该值基于哪个周期(future_periods dataframe 行,如果有 10 个周期,则从 0 到 9)时间列值hourly_data 的值介于 future_periods 的开始列值和结束列值之间。

我尝试执行以下操作:

periods = pl.series(range(future_periods.height))hourly_data = hourly_data.with_columns(    (        pl.when(((future_periods.get_column('start') <p>但这给了我错误:typeerror:使用 values 参数的不支持类型“expr”调用系列构造函数</p><p>我想要实现的目标:输入:</p><pre class="brush:php;toolbar:false;">hourly_data:┌────────────────────┐│ time               ││ ---                ││ datetime           │╞════════════════════╡│ 2024-01-01 00:00:00││ 2024-01-01 01:00:00││ 2024-01-01 02:00:00││         ...        ││ 2024-03-31 23:00:00││ 2024-04-01 00:00:00││ 2024-04-01 01:00:00││         ...        ││ 2024-06-01 00:00:00│└────────────────────┘future_periods:┌─────────────────────────┬───────────────────────┐│ start                   ┆ end                   ││ ---                     ┆ ---                   ││ datetime                ┆ datetime              │╞═════════════════════════╪═══════════════════════╡│ 2024-01-01 00:00:00     ┆ 2024-01-31 23:00:00   ││ 2024-02-01 00:00:00     ┆ 2024-02-28 23:00:00   ││ 2024-03-01 00:00:00     ┆ 2024-03-31 23:00:00   ││ 2024-04-01 00:00:00     ┆ 2024-05-31 23:00:00   │└─────────────────────────┴───────────────────────┘

输出:

hourly_data:┌─────────────────────────┬────────┐│ time                    ┆ period ││ ---                     ┆ ---    ││ datetime                ┆ int    │╞═════════════════════════╪════════╡│ 2024-01-01 00:00:00     ┆ 0      ││ 2024-01-01 01:00:00     ┆ 0      ││ 2024-01-01 02:00:00     ┆ 0      ││          ...            ┆ ...    ││ 2024-03-31 23:00:00     ┆ 2      ││ 2024-04-01 00:00:00     ┆ 3      ││ 2024-04-01 01:00:00     ┆ 3      ││          ...            ┆ ...    ││ 2024-06-01 00:00:00     ┆ None   │└─────────────────────────┴────────┘

正确答案


一般来说,它是不等式连接,或者在您的情况下,在范围内连接。这是执行此操作的一种方法。让我们首先创建一些示例数据:

hourly_data = pl.dataframe({    "time": ['2023-01-01 14:00','2023-01-02 09:00', '2023-01-04 11:00']}).lazy()future_periods = pl.dataframe({    "id": [1,2,3,4],    "start": ['2023-01-01 11:00','2023-01-02 10:00', '2023-01-03 15:00', '2023-01-04 10:00'],    "end": ['2023-01-01 16:00','2023-01-02 11:00', '2023-01-03 18:00', '2023-01-04 15:00']}).lazy()┌──────────────────┬──────┐│ time             ┆ data ││ ---              ┆ ---  ││ str              ┆ str  │╞══════════════════╪══════╡│ 2023-01-01 14:00 ┆ a    ││ 2023-01-02 09:00 ┆ b    ││ 2023-01-04 11:00 ┆ c    │└──────────────────┴──────┘ ┌─────┬──────────────────┬──────────────────┐│ id  ┆ start            ┆ end              ││ --- ┆ ---              ┆ ---              ││ i64 ┆ str              ┆ str              │╞═════╪══════════════════╪══════════════════╡│ 1   ┆ 2023-01-01 11:00 ┆ 2023-01-01 16:00 ││ 2   ┆ 2023-01-02 10:00 ┆ 2023-01-02 11:00 ││ 3   ┆ 2023-01-03 15:00 ┆ 2023-01-03 18:00 ││ 4   ┆ 2023-01-04 10:00 ┆ 2023-01-04 15:00 │└─────┴──────────────────┴──────────────────┘

现在,您可以分两步完成 - 首先,计算 time 和未来时段 id 之间的链接:

time_periods = (   hourly_data       .join(future_periods, how="cross")       .filter(           pl.col("time") &gt; pl.col("start"),           pl.col("time") <p>然后您可以将其与原始数据框连接起来:</p><pre class="brush:py;toolbar:false;">hourly_data.join(time_periods, how="left", on="time").collect()┌──────────────────┬──────┬──────┐│ time             ┆ data ┆ id   ││ ---              ┆ ---  ┆ ---  ││ str              ┆ str  ┆ i64  │╞══════════════════╪══════╪══════╡│ 2023-01-01 14:00 ┆ a    ┆ 1    ││ 2023-01-02 09:00 ┆ b    ┆ null ││ 2023-01-04 11:00 ┆ c    ┆ 4    │└──────────────────┴──────┴──────┘

执行此操作的另一种方法可能是使用 duckdb 感谢 与 polars 集成:

import duckdbimport polars as plduckdb.sql("""    select        h.time, h.data, p.id    from hourly_data as h        left join future_periods as p on            p.start  h.time""").pl()┌──────────────────┬──────┬──────┐│ time             ┆ data ┆ id   ││ ---              ┆ ---  ┆ ---  ││ str              ┆ str  ┆ i64  │╞══════════════════╪══════╪══════╡│ 2023-01-01 14:00 ┆ A    ┆ 1    ││ 2023-01-04 11:00 ┆ C    ┆ 4    ││ 2023-01-02 09:00 ┆ B    ┆ null │└──────────────────┴──────┴──────┘