1.4.1 Parsing
Polars has four temporal dtypes, and each crosses into Racket as a gregor value:
'date: days since the UNIX epoch, as a 32-bit integer; a gregor date.
'(datetime unit #f): a 64-bit count of milliseconds, microseconds or nanoseconds since the epoch; a gregor datetime. With a time zone, '(datetime unit "Zone/Name"), a gregor moment (Time zones).
'(duration unit): a time delta; a gregor period.
'time: nanoseconds since midnight; a gregor time.
1.4.1.1 Parsing dates from a file
Reading a CSV file with its dates parsed, #:try-parse-dates, is covered with the other reading options in Parsing dates.
1.4.1.2 Casting strings to dates
str->date parses a string column with a chrono format:
> (define df (~> (read-csv "apple_stock.csv") (with-columns (str->date "Date" #:format "%Y-%m-%d")))) > 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 │
└────────────┴────────┘
1.4.1.3 Extracting date features
dt-year and the other dt- operations read a field of a date column:
> (with-columns df (~> (col "Date") dt-year (alias "year")))
shape: (100, 3)
┌────────────┬────────┬──────┐
│ Date ┆ Close ┆ year │
│ --- ┆ --- ┆ --- │
│ date ┆ f64 ┆ i32 │
╞════════════╪════════╪══════╡
│ 1981-02-23 ┆ 24.62 ┆ 1981 │
│ 1981-05-06 ┆ 27.38 ┆ 1981 │
│ 1981-05-18 ┆ 28.0 ┆ 1981 │
│ 1981-09-25 ┆ 14.25 ┆ 1981 │
│ 1982-07-08 ┆ 11.0 ┆ 1982 │
│ … ┆ … ┆ … │
│ 2012-05-16 ┆ 546.08 ┆ 2012 │
│ 2012-12-04 ┆ 575.85 ┆ 2012 │
│ 2013-07-05 ┆ 417.42 ┆ 2013 │
│ 2013-11-07 ┆ 512.49 ┆ 2013 │
│ 2014-02-25 ┆ 522.06 ┆ 2014 │
└────────────┴────────┴──────┘
1.4.1.4 Mixed offsets
Datetimes with mixed UTC offsets, as on either side of a daylight-saving change, parse to UTC. Pass str->datetime a target zone with #:time-zone, or convert after parsing with dt-convert-time-zone:
> (define mixed (dataframe (list (series '("2021-03-27T00:00:00+0100" "2021-03-28T00:00:00+0100" "2021-03-29T00:00:00+0200" "2021-03-30T00:00:00+0200") #:name "data"))))
> (define mixed-parsed (~> mixed (select (~> (str->datetime "data" #:format "%Y-%m-%dT%H:%M:%S%z") (dt-convert-time-zone "Europe/Brussels"))) (ref "data"))) > mixed-parsed
shape: (4,)
Series: 'data' [datetime[us, 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
]
1.4.1.5 Dates from Racket values
A series of gregor dates is a date column, and a date column’s values come back as gregor dates:
> (define closes (series (list (date 1995 10 16) (date 1995 11 1)) #:name "Date")) > closes
shape: (2,)
Series: 'Date' [date]
[
1995-10-16
1995-11-01
]
> (series->list closes) '(#<date 1995-10-16> #<date 1995-11-01>)
gregor datetimes make a microsecond column, as Python’s datetimes do. gregor’s reach the nanosecond: a value with a sub-microsecond part makes the column nanoseconds when a nanosecond column, which spans 1677 to 2262, holds every value, and otherwise the part is floored:
> (series (list (datetime 1995 10 16 9 30 0 123456789) (datetime 1995 11 1)) #:name "precise")
shape: (2,)
Series: 'precise' [datetime[ns]]
[
1995-10-16 09:30:00.123456789
1995-11-01 00:00:00
]
> (series (list (datetime 1995 10 16 9 30 0 123456789) (datetime 1600 1 1)) #:name "wide")
shape: (2,)
Series: 'wide' [datetime[us]]
[
1995-10-16 09:30:00.123456
1600-01-01 00:00:00
]