Skip to content

Commit

Permalink
feat[rust, python]: add missing "millisecond" and "microsecond" acces…
Browse files Browse the repository at this point in the history
…sors for datetime exprs/series (#4932)
  • Loading branch information
alexander-beedie committed Sep 22, 2022
1 parent 17e7cd6 commit 06f271c
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 55 deletions.
20 changes: 18 additions & 2 deletions polars/polars-lazy/src/dsl/dt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,19 @@ impl DateLikeNameSpace {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Day))
}

/// Get the ordinal_day of a Date/Datetime
pub fn ordinal_day(self) -> Expr {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::OrdinalDay))
}

/// Get the hour of a Datetime/Time64
pub fn hour(self) -> Expr {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Hour))
}

/// Get the minute of a Datetime/Time64
pub fn minute(self) -> Expr {
self.0
Expand All @@ -153,10 +156,23 @@ impl DateLikeNameSpace {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Second))
}
/// Get the nanosecond of a Time64

/// Get the millisecond of a Time64 (scaled from nanosecs)
pub fn millisecond(self) -> Expr {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Millisecond))
}

/// Get the microsecond of a Time64 (scaled from nanosecs)
pub fn microsecond(self) -> Expr {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Microsecond))
}

/// Get the nanosecond part of a Time64
pub fn nanosecond(self) -> Expr {
self.0
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::NanoSecond))
.map_private(FunctionExpr::TemporalExpr(TemporalFunction::Nanosecond))
}

pub fn timestamp(self, tu: TimeUnit) -> Expr {
Expand Down
15 changes: 12 additions & 3 deletions polars/polars-lazy/src/dsl/function_expr/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ pub enum TemporalFunction {
Hour,
Minute,
Second,
NanoSecond,
Millisecond,
Microsecond,
Nanosecond,
TimeStamp(TimeUnit),
}

Expand All @@ -36,7 +38,9 @@ impl Display for TemporalFunction {
Hour => "hour",
Minute => "minute",
Second => "second",
NanoSecond => "nanosecond",
Millisecond => "millisecond",
Microsecond => "microsecond",
Nanosecond => "nanosecond",
TimeStamp(tu) => return write!(f, "dt.timestamp({})", tu),
};
write!(f, "dt.{}", s)
Expand Down Expand Up @@ -76,10 +80,15 @@ pub(super) fn minute(s: &Series) -> PolarsResult<Series> {
pub(super) fn second(s: &Series) -> PolarsResult<Series> {
s.second().map(|ca| ca.into_series())
}
pub(super) fn millisecond(s: &Series) -> PolarsResult<Series> {
s.nanosecond().map(|ca| (ca / 1_000_000).into_series())
}
pub(super) fn microsecond(s: &Series) -> PolarsResult<Series> {
s.nanosecond().map(|ca| (ca / 1_000).into_series())
}
pub(super) fn nanosecond(s: &Series) -> PolarsResult<Series> {
s.nanosecond().map(|ca| ca.into_series())
}

pub(super) fn timestamp(s: &Series, tu: TimeUnit) -> PolarsResult<Series> {
s.timestamp(tu).map(|ca| ca.into_series())
}
4 changes: 3 additions & 1 deletion polars/polars-lazy/src/dsl/function_expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,9 @@ impl From<TemporalFunction> for SpecialEq<Arc<dyn SeriesUdf>> {
Hour => map!(datetime::hour),
Minute => map!(datetime::minute),
Second => map!(datetime::second),
NanoSecond => map!(datetime::nanosecond),
Millisecond => map!(datetime::millisecond),
Microsecond => map!(datetime::microsecond),
Nanosecond => map!(datetime::nanosecond),
TimeStamp(tu) => map!(datetime::timestamp, tu),
}
}
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-lazy/src/dsl/function_expr/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl FunctionExpr {
let dtype = match fun {
Year | IsoYear => DataType::Int32,
Month | Quarter | Week | WeekDay | Day | OrdinalDay | Hour | Minute
| NanoSecond | Second => DataType::UInt32,
| Millisecond | Microsecond | Nanosecond | Second => DataType::UInt32,
TimeStamp(_) => DataType::Int64,
};
with_dtype(dtype)
Expand Down
3 changes: 3 additions & 0 deletions py-polars/docs/source/reference/expression.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ The following methods are available under the `expr.dt` attribute.
ExprDateTimeNameSpace.epoch
ExprDateTimeNameSpace.hour
ExprDateTimeNameSpace.hours
ExprDateTimeNameSpace.microsecond
ExprDateTimeNameSpace.microseconds
ExprDateTimeNameSpace.millisecond
ExprDateTimeNameSpace.milliseconds
ExprDateTimeNameSpace.minute
ExprDateTimeNameSpace.minutes
Expand Down
3 changes: 3 additions & 0 deletions py-polars/docs/source/reference/series.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ The following methods are available under the `Series.dt` attribute.
DateTimeNameSpace.max
DateTimeNameSpace.mean
DateTimeNameSpace.median
DateTimeNameSpace.microsecond
DateTimeNameSpace.microseconds
DateTimeNameSpace.millisecond
DateTimeNameSpace.milliseconds
DateTimeNameSpace.min
DateTimeNameSpace.minute
Expand Down
59 changes: 41 additions & 18 deletions py-polars/polars/internals/expr/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def year(self) -> pli.Expr:
"""
Extract year from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the year number in the calendar date.
Expand Down Expand Up @@ -198,9 +198,9 @@ def iso_year(self) -> pli.Expr:
"""
Extract iso-year from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the year number in the iso standard.
Returns the year number in the ISO standard.
This may not correspond with the calendar year.
Returns
Expand All @@ -214,7 +214,7 @@ def quarter(self) -> pli.Expr:
"""
Extract quarter from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the quarter ranging from 1 to 4.
Expand Down Expand Up @@ -262,7 +262,7 @@ def month(self) -> pli.Expr:
"""
Extract month from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the month number starting from 1.
The return value ranges from 1 to 12.
Expand Down Expand Up @@ -311,7 +311,7 @@ def week(self) -> pli.Expr:
"""
Extract the week from the underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the ISO week number starting from 1.
The return value ranges from 1 to 53. (The last week of year differs by years.)
Expand Down Expand Up @@ -360,7 +360,7 @@ def weekday(self) -> pli.Expr:
"""
Extract the week day from the underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the weekday number where monday = 0 and sunday = 6
Expand Down Expand Up @@ -414,7 +414,7 @@ def day(self) -> pli.Expr:
"""
Extract day from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the day of month starting from 1.
The return value ranges from 1 to 31. (The last day of month differs by months.)
Expand Down Expand Up @@ -469,7 +469,7 @@ def ordinal_day(self) -> pli.Expr:
"""
Extract ordinal day from underlying Date representation.
Can be performed on Date and Datetime columns.
Applies to Date and Datetime columns.
Returns the day of year starting from 1.
The return value ranges from 1 to 366. (The last day of year differs by years.)
Expand Down Expand Up @@ -524,7 +524,7 @@ def hour(self) -> pli.Expr:
"""
Extract hour from underlying DateTime representation.
Can be performed on Datetime columns.
Applies to Datetime columns.
Returns the hour number from 0 to 23.
Expand Down Expand Up @@ -572,7 +572,7 @@ def minute(self) -> pli.Expr:
"""
Extract minutes from underlying DateTime representation.
Can be performed on Datetime columns.
Applies to Datetime columns.
Returns the minute number from 0 to 59.
Expand Down Expand Up @@ -622,7 +622,7 @@ def second(self, fractional: bool = False) -> pli.Expr:
"""
Extract seconds from underlying DateTime representation.
Can be performed on Datetime columns.
Applies to Datetime columns.
Returns the integer second number from 0 to 59, or a floating
point number from 0 < 60 if ``fractional=True`` that includes
Expand Down Expand Up @@ -693,18 +693,41 @@ def second(self, fractional: bool = False) -> pli.Expr:
else sec
)

def nanosecond(self) -> pli.Expr:
def millisecond(self) -> pli.Expr:
"""
Extract seconds from underlying DateTime representation.
Extract milliseconds from underlying DateTime representation.
Applies to Datetime columns.
Returns
-------
Milliseconds as UInt32
"""
return pli.wrap_expr(self._pyexpr.millisecond())

def microsecond(self) -> pli.Expr:
"""
Extract microseconds from underlying DateTime representation.
Applies to Datetime columns.
Returns
-------
Microseconds as UInt32
Can be performed on Datetime columns.
"""
return pli.wrap_expr(self._pyexpr.microsecond())

def nanosecond(self) -> pli.Expr:
"""
Extract nanoseconds from underlying DateTime representation.
Returns the number of nanoseconds since the whole non-leap second.
The range from 1,000,000,000 to 1,999,999,999 represents the leap second.
Applies to Datetime columns.
Returns
-------
Nanosecond as UInt32
Nanoseconds as UInt32
"""
return pli.wrap_expr(self._pyexpr.nanosecond())
Expand Down

0 comments on commit 06f271c

Please sign in to comment.