Search code examples
rustrust-polars

Add a new Date column based off an existing Date column in rust polars


I am trying to add a new column in my polars DataFrame: 'for_date'

There is already a column named 'made_on', and I want 'for_date' to be 1 day greater than 'made_on'. So if 'made_on' is 2022-12-25 then for_date should be 2022-12-26 etc.

My df looks like this:

┌────────────┐
│ made_on    │
│ ---        │
│ date       │
╞════════════╡
│ 2021-06-04 │
│ 2021-12-31 │
│ 2021-12-31 │
│ 2021-12-30 │
│ ...        │
│ 2022-08-06 │
│ 2022-08-06 │
│ 2022-08-06 │
│ 2022-08-06 │
└────────────┘

I know I can use with_column() on the df to transform a column but can't seem to get the types working and as a Rust newbie it's driving me a bit mad! In pseudo code I am looking for:

let df = df.with_column((col("made_on").map(/* add one day */).alias("for_date"))

Solution

  • If you ensure you have the dtype-duration and temporal features enabled for the polars crate (these features may be on by default in some setups or versions):

    polars = { version = "0.27.2", features = ["dtype-duration", "lazy", "temporal"] }
    

    Then you can simply add a Chrono Duration to the date/time column you have:

    use polars::{prelude::*, export::chrono};
    
    fn main() -> PolarsResult<()> {
        let df = CsvReader::from_path("example.csv")?
            .infer_schema(None)
            .has_header(true)
            .with_parse_dates(true)
            .finish()?
            .lazy()
            .with_column(
                (col("made_on") + chrono::Duration::days(1).lit()).alias("for_date")
            );
    
        println!("{:?}", df.collect());
    
        Ok(())
    }
    

    This is not very well documented through examples, but the corresponding RustDocs for the literal values of Chrono Duration shed some light.