如何基于其他 DataFrame 行过滤器创建列?
我有一个名为“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') <= pl.col('time')) & (pl.col('time') <= future_periods.get_column('end'))).any())
.then(periods.filter(pl.series((future_periods.get_column('start') <= pl.col('real_time')) & (pl.col('real_time') <= future_periods.get_column('end')))).to_list()[0])
.otherwise(none)
).alias('period')
)
但这给了我错误:typeerror:使用 values
参数的不支持类型“expr”调用系列构造函数
我想要实现的目标: 输入:
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") > pl.col("start"),
pl.col("time") < pl.col("end")
).select(["time","id"])
)
┌──────────────────┬─────┐
│ time ┆ id │
│ --- ┆ --- │
│ str ┆ i64 │
╞══════════════════╪═════╡
│ 2023-01-01 14:00 ┆ 1 │
│ 2023-01-04 11:00 ┆ 4 │
└──────────────────┴─────┘
然后您可以将其与原始数据框连接起来:
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 duckdb
import polars as pl
duckdb.sql("""
select
h.time, h.data, p.id
from hourly_data as h
left join future_periods as p on
p.start < h.time and
p.end > 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 │
└──────────────────┴──────┴──────┘
以上就是如何基于其他 DataFrame 行过滤器创建列?的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
如何基于其他 DataFrame 行过滤器创建列?
下载Word文档到电脑,方便收藏和打印~