我正在将代码从 Pandas 迁移到 Polars。我有由时间戳和值列组成的时间序列数据,我需要计算一堆特征。即
from datetime import datetime, timedelta
df = pl.DataFrame({
"timestamp": pl.datetime_range(
datetime(2017, 1, 1),
datetime(2018, 1, 1),
timedelta(minutes=15),
time_zone="Australia/Sydney",
time_unit="ms", eager=True),
})
value = np.random.normal(0, 1, len(df))
df = df.with_columns([pl.Series(value).alias("value")])
如果时间戳是标准时间或夏令时,我需要生成一个包含指示器的列。我目前正在使用
map_elements
,因为据我所知,它不是 Temporal Expr,即我当前的代码是
def dst(timestamp:datetime):
return int(timestamp.dst().total_seconds()!=0)
df = df.with_columns(pl.struct("timestamp").map_elements(lambda x: dst(**x)).alias("dst"))
(这使用了一个技巧,可以有效地检查
tzinfo.dst(dt)
偏移量是否为零)
有没有一种(快速)方法可以使用
polars expressions
而不是(慢)map_elements
来做到这一点?
与
polars>=0.18.5
以下作品
df = df.with_columns((pl.col("timestamp").dt.dst_offset()==0).cast(pl.Int32).alias("dst"))
您可以为此利用
strftime
。
(
df
.with_columns(
dst=pl.when(pl.col('timestamp').dt.strftime("%Z").str.contains("(DT$)"))
.then(True)
.otherwise(False)
)
)
它依靠以“DT”结尾的本地时区来确定夏令时状态。这在这里有效,也适用于美国时区(即 EST/EDT、CST/CDT 等),但不起作用的例子有很多。
您也可以使用 utc 偏移量,但它要复杂得多。
(
df
.with_columns(
tzoff=pl.col('timestamp').dt.strftime("%z").cast(pl.Int64())
)
.join(
df
.select(
tzoff=pl.col('timestamp').dt.strftime("%z").cast(pl.Int64())
)
.unique('tzoff')
.sort('tzoff')
.with_columns(
dst=pl.lit([False, True])
),
on='tzoff')
.drop('tzoff')
)
此假设时区只有 2 个偏移量,两者中较小的一个是标准时间,较大的一个是夏令时。