我正在评估
polars
的时间序列特征提取 - 例如复制 tsfresh
等库的功能。
我的基础知识运行得非常好,即使用
dynamic grouping
创建窗口,并且大多数基本 tsfel
功能可以直接重新实现为 polars
自定义函数(也许我可以对此进行优化,但目前性能还不错),即
def var_larger_than_std(x: pl.Series) -> bool:
"""
Is variance higher than the standard deviation?
Boolean variable denoting if the variance of x is greater than its standard deviation. Is equal to variance of x
being larger than 1
:param x: the time series to calculate the feature of
:type x: pl.Series
:return: the value of this feature
:return type: bool
"""
y = x.var()
return y > np.sqrt(y)
q = (
dataset.lazy() \
.group_by_dynamic("ts_local", every="1d", group_by="id") \
.agg(
pl.col("value").count().alias("value__count"),
var_larger_than_std(pl.col("value")).alias("value__var_larger_than_std"),
)
)
q.collect()
对于基本特征图
f(series)->series
这工作得很好。尽管复杂的特征图产生多个输出是很常见的。例如 fft_coefficient 产生多个输出。在 tsfel
中,它们作为 dict
返回,并且每个 key:value
在最终 pandas.Series
中扩展为单独的 pandas.Dataframe
。
我怎样才能在
polars
中复制这个?说我有这个功能
def complex_feature(x: pl.Series) -> Dict[str, float]:
return {"col1":0.0, "col2":1.0}
q = (
dataset.lazy() \
.group_by_dynamic("ts_local", every="1d", group_by="id") \
.agg(
complex_feature(pl.col("value")).???,
)
)
q.collect()
┌────────────────────────────────────┬──────┬──────┐
│ ts_local ┆ col1 ┆ col2 │
│ -------- ┆ ---- ┆ ---- │
│ timestamp[ns,tz=Australia/Sydney] ┆ f64 ┆ f64 │
╞════════════════════════════════════╪══════╪══════╡
│ 2023-01-01 ┆ 0.0 ┆ 1.0 │
└────────────────────────────────────┴──────┴──────┘
即该字典被扩展为单独的列(它不必是一个字典,我可以返回一个 pl.Series 的元组或任何有效的)
我不确定这是否是最好的方法,但调用
unnest
似乎可以做我想做的事,即
def complex_feature(x: pl.Series) -> Dict[str, float]:
return {"col1":0.0, "col2":1.0}
q = (
dataset.lazy() \
.group_by_dynamic("ts_local", every="1d", group_by="id") \
.agg(
complex_feature(pl.col("value")).alias("value__complex_feature"),
)
.unnest("value__complex_feature")
)
q.collect()
它接受一个字符串或列表或字符串(我还找到了对
unnest_all
的引用,但它们可能已经过时了。