使用Polars根据采样率与采样数量生成采样时间戳数组
使用Polars根据采样率与采样数量生成采样时间戳数组
我来帮你搞定这个Polars里生成采样时间戳数组的问题~ 你的需求很明确:给每行数据生成对应所有采样点的时间戳数组,而且要适配每行不同的采样率和采样数量,不用硬编码固定值对吧?
首先先确认你的原始数据结构:
import polars as pl from datetime import datetime, timedelta df = pl.DataFrame( { "sample_started_at": [ datetime(2022, 1, 1, hour=1, minute=1, second=1), datetime(2022, 1, 1, hour=2, minute=1, second=1), datetime(2022, 1, 1, hour=3, minute=1, second=1) ], "sample_rate": [25600, 25600, 51200], "sample_size": [100, 200, 100], } )
这里的核心是利用Polars的向量化操作直接处理整列数据,避免逐行循环,这样性能会好很多。直接用pl.datetime_ranges就可以实现,它支持把列作为参数传入,完美适配每行不同的参数:
result_df = df.with_columns( sample_timestamps=pl.datetime_ranges( # 采样起始时间,直接用原列 start=pl.col("sample_started_at"), # 计算采样结束时间:起始时间 + 总采样时长(采样数量/采样率 秒) end=pl.col("sample_started_at") + pl.duration(seconds=pl.col("sample_size") / pl.col("sample_rate")), # 计算采样间隔:1/采样率 秒,转换成纳秒传入保证精度 interval=pl.duration(nanoseconds=1_000_000_000 / pl.col("sample_rate")), # 左闭合,确保包含起始时间,且生成的数组长度正好等于sample_size closed="left" ) ) # 查看结果 print(result_df)
代码关键说明:
pl.datetime_ranges是Polars专门生成时间序列的函数,支持向量化输入,比逐行处理效率高很多- 总采样时长是
sample_size / sample_rate,也就是采样数量除以每秒采样数,得到整个采样过程的秒数 - 采样间隔用纳秒计算是为了避免浮点误差,保证时间戳的准确性
closed="left"设置确保生成的数组包含起始时间,且不包含结束时间,这样数组长度正好等于sample_size(比如100个采样点就对应100个时间戳)
如果你的Polars版本比较旧(比如0.18.x及以前),datetime_ranges可能不支持列作为参数,这时候可以用map_elements逐行处理,兼容性更好:
result_df = df.with_columns( sample_timestamps=pl.struct(["sample_started_at", "sample_rate", "sample_size"]) .map_elements( lambda row: pl.datetime_ranges( start=row["sample_started_at"], end=row["sample_started_at"] + timedelta(seconds=row["sample_size"]/row["sample_rate"]), interval=timedelta(seconds=1/row["sample_rate"]), closed="left" ).to_list(), return_dtype=pl.List(pl.Datetime) ) )
这种方法兼容性强,但性能不如向量化版本,大数据集下更推荐第一种方案。
备注:内容来源于stack exchange,提问作者LeonBam
相关产品推荐
相关产品推荐

