跳到内容

筛选

过滤日期列的方式与过滤其他类型的列相同,都使用 .filter 方法。

Polars 使用 Python 原生的 datetimedatetimedelta 用于 pl.Datetimepl.Datepl.Duration 这些数据类型之间的相等比较。

在以下示例中,我们使用 Apple 股票价格的时间序列数据。

read_csv

import polars as pl
from datetime import datetime

df = pl.read_csv("docs/assets/data/apple_stock.csv", try_parse_dates=True)
print(df)

CsvReader · 在功能 csv 上可用

let df = CsvReadOptions::default()
    .map_parse_options(|parse_options| parse_options.with_try_parse_dates(true))
    .try_into_reader_with_file_path(Some("docs/assets/data/apple_stock.csv".into()))
    .unwrap()
    .finish()
    .unwrap();
println!("{}", &df);

shape: (100, 2)
┌────────────┬────────┐
│ Date       ┆ Close  │
│ ---        ┆ ---    │
│ date       ┆ f64    │
╞════════════╪════════╡
│ 1981-02-23 ┆ 24.62  │
│ 1981-05-06 ┆ 27.38  │
│ 1981-05-18 ┆ 28.0   │
│ 1981-09-25 ┆ 14.25  │
│ 1982-07-08 ┆ 11.0   │
│ …          ┆ …      │
│ 2012-05-16 ┆ 546.08 │
│ 2012-12-04 ┆ 575.85 │
│ 2013-07-05 ┆ 417.42 │
│ 2013-11-07 ┆ 512.49 │
│ 2014-02-25 ┆ 522.06 │
└────────────┴────────┘

按单个日期过滤

我们可以按单个日期过滤,在过滤表达式中使用相等比较。

filter

filtered_df = df.filter(
    pl.col("Date") == datetime(1995, 10, 16),
)
print(filtered_df)

filter

let filtered_df = df
    .clone()
    .lazy()
    .filter(col("Date").eq(lit(NaiveDate::from_ymd_opt(1995, 10, 16).unwrap())))
    .collect()?;
println!("{}", &filtered_df);

shape: (1, 2)
┌────────────┬───────┐
│ Date       ┆ Close │
│ ---        ┆ ---   │
│ date       ┆ f64   │
╞════════════╪═══════╡
│ 1995-10-16 ┆ 36.13 │
└────────────┴───────┘

请注意,我们使用的是小写 datetime 方法,而不是大写 Datetime 数据类型。

按日期范围过滤

我们可以按日期范围过滤,在过滤表达式中使用 is_between 方法,指定开始日期和结束日期。

filter · is_between

filtered_range_df = df.filter(
    pl.col("Date").is_between(datetime(1995, 7, 1), datetime(1995, 11, 1)),
)
print(filtered_range_df)

filter · is_between · 在功能 is_between 上可用

let filtered_range_df = df
    .clone()
    .lazy()
    .filter(
        col("Date")
            .gt(lit(NaiveDate::from_ymd_opt(1995, 7, 1).unwrap()))
            .and(col("Date").lt(lit(NaiveDate::from_ymd_opt(1995, 11, 1).unwrap()))),
    )
    .collect()?;
println!("{}", &filtered_range_df);

shape: (2, 2)
┌────────────┬───────┐
│ Date       ┆ Close │
│ ---        ┆ ---   │
│ date       ┆ f64   │
╞════════════╪═══════╡
│ 1995-07-06 ┆ 47.0  │
│ 1995-10-16 ┆ 36.13 │
└────────────┴───────┘

过滤负日期

假设您正在与一位考古学家合作,并且正在处理负日期。Polars 可以很好地解析和存储它们,但 Python 的 datetime 库不支持。因此,在过滤时,您应该使用 .dt 命名空间中的属性。

str.to_date

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)

str.replace_all · 在功能 dtype-date 上可用

    let negative_dates_df = df!(
    "ts"=> &["-1300-05-23", "-1400-03-02"],
    "values"=> &[3, 4])?
    .lazy()
    .with_column(col("ts").str().to_date(StrptimeOptions::default()))
    .collect()?;

    let negative_dates_filtered_df = negative_dates_df
        .clone()
        .lazy()
        .filter(col("ts").dt().year().lt(-1300))
        .collect()?;
    println!("{}", &negative_dates_filtered_df);

shape: (1, 2)
┌─────────────┬────────┐
│ ts          ┆ values │
│ ---         ┆ ---    │
│ date        ┆ i64    │
╞═════════════╪════════╡
│ -1400-03-02 ┆ 4      │
└─────────────┴────────┘