Polars中是否有类似Pandas基于datetime列的数值插值方法?
Polars中基于Datetime列的数值插值方法
Pandas中的实现方式
你提到的Pandas中基于datetime列的数值插值实现如下:
import polars as pl from datetime import datetime df1 = pl.DataFrame( { "ts": [ datetime(2020, 1, 1), datetime(2020, 1, 3, 0, 0, 12), datetime(2020, 1, 3, 0, 1, 35), datetime(2020, 1, 4), ], "value": [1, None, None, 3], } )
通过转为Pandas DataFrame后使用interpolate(method='index')实现基于时间索引的线性插值:
df1.to_pandas().set_index('ts').interpolate(method='index')
输出结果:
value ts 2020-01-01 00:00:00 1.000000 2020-01-03 00:00:12 2.333426 2020-01-03 00:01:35 2.334066 2020-01-04 00:00:00 3.000000
Polars中的等效实现
Polars可以通过两种方式实现和Pandasmethod='index'一致的时间线性插值效果:
方法1:利用interpolate结合时间戳转换
将datetime列转为数值类型(Unix时间戳),然后基于该数值列对value执行线性插值:
import polars as pl from datetime import datetime df1 = pl.DataFrame( { "ts": [ datetime(2020, 1, 1), datetime(2020, 1, 3, 0, 0, 12), datetime(2020, 1, 3, 0, 1, 35), datetime(2020, 1, 4), ], "value": [1, None, None, 3], } ) result = df1.with_columns( pl.col("ts").cast(pl.Int64).alias("ts_ms") ).interpolate( method="linear", by="ts_ms" ).drop("ts_ms") print(result)
输出结果:
shape: (4, 2) ┌─────────────────────┬───────────┐ │ ts ┆ value │ │ --- ┆ --- │ │ datetime[μs] ┆ f64 │ ╞═════════════════════╪═══════════╡ │ 2020-01-01 00:00:00 ┆ 1.0 │ │ 2020-01-03 00:00:12 ┆ 2.333426 │ │ 2020-01-03 00:01:35 ┆ 2.334066 │ │ 2020-01-04 00:00:00 ┆ 3.0 │ └─────────────────────┴───────────┘
方法2:手动计算线性插值(自定义逻辑)
如果需要更灵活的控制,可以通过窗口函数获取前后非空的数值和时间,手动推导插值结果:
result = df1.with_columns( # 获取前一个非空value及对应时间 pl.col("value").forward_fill().alias("prev_val"), pl.col("ts").forward_fill().alias("prev_ts"), # 获取后一个非空value及对应时间 pl.col("value").backward_fill().alias("next_val"), pl.col("ts").backward_fill().alias("next_ts") ).with_columns( # 基于时间比例计算线性插值 pl.when(pl.col("value").is_null()) .then( pl.col("prev_val") + (pl.col("next_val") - pl.col("prev_val")) * (pl.col("ts").cast(pl.Int64) - pl.col("prev_ts").cast(pl.Int64)) / (pl.col("next_ts").cast(pl.Int64) - pl.col("prev_ts").cast(pl.Int64)) ) .otherwise(pl.col("value")) .alias("value") ).drop(["prev_val", "prev_ts", "next_val", "next_ts"]) print(result)
该方法会得到和上述完全一致的结果,适合需要调整插值逻辑的场景。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

