1050 字
5 分钟
阅读量加载中...
polars学习-10-时间序列类型

背景#

polars学习系列文章,第10篇 时间序列类型(Time series)

该系列文章会分享到github,大家可以去下载jupyter文件,进行参考学习 仓库地址:https://github.com/DataShare-duo/polars_learn

小编运行环境#

import sys
print('python 版本:',sys.version.split('|')[0])
#python 版本: 3.11.9
import polars as pl
print("polars 版本:",pl.__version__)
#polars 版本: 1.2.1

日期时间类型#

Polars 原生支持解析时间序列数据,而且能执行一些复杂的操作

包含的日期时间类型:

  • Date:日期类型,例如:2014-07-08,内部表示为自1970-01-01的天数,用32位有符号整数表示
  • Datetime:日期时间类型,例如:2014-07-08 07:00:00
  • Duration:时间间隔类型
  • Time:时间类型

从文件加载数据时,解析时间#

从csv文件加载数据时,可以指定 try_parse_dates=True,让polars去尝试解析日期时间

df = pl.read_csv("./data/apple_stock.csv", try_parse_dates=True)
print(df)
#shape: (100, 2)
┌────────────┬────────┐
│ Date ┆ Close │
------
│ date ┆ f64 │
╞════════════╪════════╡
1981-02-2324.62
1981-05-0627.38
1981-05-1828.0
1981-09-2514.25
1982-07-0811.0
│ … ┆ … │
2012-05-16546.08
2012-12-04575.85
2013-07-05417.42
2013-11-07512.49
2014-02-25522.06
└────────────┴────────┘

字符串转换为日期时间类型#

通过调用字符串的 str.to_date 方法,需要指定日期时间解析时的格式

日期时间解析格式,可参考该文档:
https://docs.rs/chrono/latest/chrono/format/strftime/index.html

df = pl.read_csv("./data/apple_stock.csv", try_parse_dates=False)
df = df.with_columns(pl.col("Date").str.to_date("%Y-%m-%d"))
print(df)
shape: (100, 2)
┌────────────┬────────┐
│ Date ┆ Close │
------
│ date ┆ f64 │
╞════════════╪════════╡
1981-02-2324.62
1981-05-0627.38
1981-05-1828.0
1981-09-2514.25
1982-07-0811.0
│ … ┆ … │
2012-05-16546.08
2012-12-04575.85
2013-07-05417.42
2013-11-07512.49
2014-02-25522.06
└────────────┴────────┘

从日期时间类型中提取特定的日期类型#

比如从日期时间类型列中提取年份、日期等,通过 .dt 来提取

df_with_year = df.with_columns(pl.col("Date").dt.year().alias("year"))
print(df_with_year)
#shape: (100, 3)
┌────────────┬────────┬──────┐
│ Date ┆ Close ┆ year │
---------
│ date ┆ f64 ┆ i32 │
╞════════════╪════════╪══════╡
1981-02-2324.621981
1981-05-0627.381981
1981-05-1828.01981
1981-09-2514.251981
1982-07-0811.01982
│ … ┆ … ┆ … │
2012-05-16546.082012
2012-12-04575.852012
2013-07-05417.422013
2013-11-07512.492013
2014-02-25522.062014
└────────────┴────────┴──────┘

混合时差#

当有混合时差(例如,由于跨越夏令时),可以使用 dt.convert_time_zone 来进行转换

data = [
"2021-03-27T00:00:00+0100",
"2021-03-28T00:00:00+0100",
"2021-03-29T00:00:00+0200",
"2021-03-30T00:00:00+0200",
]
mixed_parsed = (
pl.Series(data)
.str.to_datetime("%Y-%m-%dT%H:%M:%S%z")
.dt.convert_time_zone("Europe/Brussels")
)
print(mixed_parsed)
#shape: (4,)
Series: '' [datetime[μs, Europe/Brussels]]
[
2021-03-27 00:00:00 CET
2021-03-28 00:00:00 CET
2021-03-29 00:00:00 CEST
2021-03-30 00:00:00 CEST
]

日期时间数据筛选#

from datetime import datetime
df = pl.read_csv("./data/apple_stock.csv", try_parse_dates=True)
print(df)
#shape: (100, 2)
┌────────────┬────────┐
│ Date ┆ Close │
------
│ date ┆ f64 │
╞════════════╪════════╡
1981-02-2324.62
1981-05-0627.38
1981-05-1828.0
1981-09-2514.25
1982-07-0811.0
│ … ┆ … │
2012-05-16546.08
2012-12-04575.85
2013-07-05417.42
2013-11-07512.49
2014-02-25522.06
└────────────┴────────┘

筛选单个日期时间对象#

filtered_df = df.filter(
pl.col("Date") == datetime(1995, 10, 16),
)
print(filtered_df)
#shape: (1, 2)
┌────────────┬───────┐
│ Date ┆ Close │
------
│ date ┆ f64 │
╞════════════╪═══════╡
1995-10-1636.13
└────────────┴───────┘

筛选一个日期范围#

通过 is_between 方法,指定一个范围

filtered_range_df = df.filter(
pl.col("Date").is_between(datetime(1995, 7, 1), datetime(1995, 11, 1)),
)
print(filtered_range_df)
#shape: (2, 2)
┌────────────┬───────┐
│ Date ┆ Close │
------
│ date ┆ f64 │
╞════════════╪═══════╡
1995-07-0647.0
1995-10-1636.13
└────────────┴───────┘

筛选 负数日期#

考古领域数据可能会涉及这类日期

ts = pl.Series(["-1300-05-23", "-1400-03-02"]).str.to_date()
negative_dates_df = pl.DataFrame({"ts": ts, "values": [3, 4]})
negative_dates_filtered_df = negative_dates_df.filter(pl.col("ts").dt.year() < -1300)
print(negative_dates_filtered_df)
#shape: (1, 2)
┌─────────────┬────────┐
│ ts ┆ values │
------
│ date ┆ i64 │
╞═════════════╪════════╡
-1400-03-024
└─────────────┴────────┘

历史相关文章#


以上是自己实践中遇到的一些问题,分享出来供大家参考学习,欢迎关注微信公众号:DataShare ,不定期分享干货

微信公众号 QQ群