Py-Polars:能否用.over()实现基于时间戳的动态分组窗口统计?
在Polars中用
.over()实现时间窗口统计 你目前用group_by_dynamic实现了按5分钟时间窗口统计唯一txn_id数量的逻辑,代码如下:
df = pl.DataFrame({ 'txn_id': ['0x5...60', '0x1...6d', '0x9...84', '0xc...25', '0x5...50', '0xe...14', '0x2...f3', '0xe...75', '0x3...95', '0x4...4e'], 'txn_grouping': ['0x4...dd', '0x4...dd', '0xf...e2', '0x4...17', '0xe...8b', '0x6...4e', '0xe...da', '0xf...f2', '0x1...21', '0xc...cf'], 'ts': [1438918233, 1438918613, 1438918630, 1438918983, 1438919175, 1438918630, 1438919451, 1438919461, 1438919491, 1438919571] }).sort('ts') (df.select(pl.exclude('ts'), (pl.col("ts") * 1000).cast(pl.Datetime('ms'))) .group_by_dynamic("ts", every = "5m") .agg(pl.n_unique("txn_id").alias("num_txs_per_5m")) )
但你希望保留原始DataFrame的所有行和字段,新增一列num_txs_per_5m来对应每行所属5分钟窗口的唯一交易数——就像你用.over()处理非时间分组的逻辑那样:
df.select(pl.col('txn_id').count().over('txn_grouping'), 'txn_grouping')
可以用.over()实现时间窗口统计吗?
完全可以。Polars支持在.over()中定义时间范围窗口,你需要先把时间戳转换为Datetime类型,然后通过时间截断或范围定义来匹配5分钟窗口。
固定5分钟窗口实现代码:
# 先转换时间戳为Datetime类型,保留原数据 df = df.with_columns( ts_datetime=(pl.col("ts") * 1000).cast(pl.Datetime("ms")) ) # 用.over()添加对应窗口的唯一交易数统计列 result = df.with_columns( num_txs_per_5m=pl.col("txn_id") .n_unique() .over( # 将每个时间戳截断到最近的5分钟起始点,作为分组键 pl.col("ts_datetime").dt.truncate("5m") ) ) print(result)
逻辑说明:
pl.col("ts_datetime").dt.truncate("5m")会把每个时间戳对齐到所属5分钟窗口的起始时间,同一窗口内的所有行将得到相同的截断值,相当于把时间窗口作为分组条件传入.over(),最终实现和group_by_dynamic一致的固定窗口统计,同时保留原始DataFrame的所有内容。
滚动时间窗口(可选):
如果需要的是以当前行为中心的滚动5分钟窗口(比如前后各2.5分钟),可以这样定义窗口范围:
result = df.with_columns( num_txs_per_5m=pl.col("txn_id") .n_unique() .over( pl.col("ts_datetime").dt.offset_by("-2m30s").alias("window_start"), pl.col("ts_datetime").dt.offset_by("2m30s").alias("window_end"), window="range" ) )
内容的提问来源于stack exchange,提问作者Cory Grinstead
相关产品推荐
相关产品推荐

