def test_datetime_to_pl_timestamp() -> None: for dt, tu, expected in ( (datetime(2121, 1, 1), "ns", 4765132800000000000), (datetime(2121, 1, 1), "us", 4765132800000000), (datetime(2121, 1, 1), "ms", 4765132800000), ): out = _datetime_to_pl_timestamp(dt, tu) assert out == expected
def maybe_cast( el: Type[DataType], dtype: Type, time_unit: Optional[str] = None ) -> Type[DataType]: # cast el if it doesn't match from polars.utils import _datetime_to_pl_timestamp, _timedelta_to_pl_timedelta if isinstance(el, datetime): return _datetime_to_pl_timestamp(el, time_unit) elif isinstance(el, timedelta): return _timedelta_to_pl_timedelta(el, time_unit) py_type = dtype_to_py_type(dtype) if not isinstance(el, py_type): el = py_type(el) return el
def date_range( low: date | datetime, high: date | datetime, interval: str | timedelta, closed: str | None = "both", name: str | None = None, time_unit: str | None = None, ) -> pli.Series: """ Create a range of type `Datetime` (or `Date`). Parameters ---------- low Lower bound of the date range. high Upper bound of the date range. interval Interval periods. It can be a python timedelta object, like ``timedelta(days=10)``, or a polars duration string, such as ``3d12h4m25s`` representing 3 days, 12 hours, 4 minutes, and 25 seconds. closed : {None, 'left', 'right', 'both', 'none'} Make the interval closed to the 'left', 'right', 'none' or 'both' sides. name Name of the output Series. time_unit : {'ns', 'us', 'ms'} Set the time unit. Notes ----- If both ``low`` and ``high`` are passed as date types (not datetime), and the interval granularity is no finer than 1d, the returned range is also of type date. All other permutations return a datetime Series. Returns ------- A Series of type `Datetime` or `Date`. Examples -------- Using polars duration string to specify the interval: >>> from datetime import date >>> pl.date_range(date(2022, 1, 1), date(2022, 3, 1), "1mo", name="drange") shape: (3,) Series: 'drange' [date] [ 2022-01-01 2022-02-01 2022-03-01 ] Using `timedelta` object to specify the interval: >>> from datetime import datetime, timedelta >>> pl.date_range( ... datetime(1985, 1, 1), ... datetime(1985, 1, 10), ... timedelta(days=1, hours=12), ... time_unit="ms", ... ) shape: (7,) Series: '' [datetime[ms]] [ 1985-01-01 00:00:00 1985-01-02 12:00:00 1985-01-04 00:00:00 1985-01-05 12:00:00 1985-01-07 00:00:00 1985-01-08 12:00:00 1985-01-10 00:00:00 ] """ if isinstance(interval, timedelta): interval = _timedelta_to_pl_duration(interval) low, low_is_date = _ensure_datetime(low) high, high_is_date = _ensure_datetime(high) if in_nanoseconds_window(low) and in_nanoseconds_window( high) and time_unit is None: tu = "ns" elif time_unit is not None: tu = time_unit else: tu = "ms" start = _datetime_to_pl_timestamp(low, tu) stop = _datetime_to_pl_timestamp(high, tu) if name is None: name = "" dt_range = pli.wrap_s( _py_date_range(start, stop, interval, closed, name, tu)) if (low_is_date and high_is_date and not _interval_granularity(interval).endswith(("h", "m", "s"))): dt_range = dt_range.cast(Date) return dt_range
def test_datetime_to_pl_timestamp() -> None: out = _datetime_to_pl_timestamp(datetime(2121, 1, 1), "ns") assert out == 4765132800000000000 out = _datetime_to_pl_timestamp(datetime(2121, 1, 1), "ms") assert out == 4765132800000
def lit( value: None | (float | int | str | date | datetime | pli.Series | np.ndarray | Any), dtype: type[DataType] | None = None, ) -> pli.Expr: """ A literal value. Parameters ---------- value Value that should be used as a `literal`. dtype Optionally define a dtype. Examples -------- Literal integer: >>> pl.lit(1) # doctest: +IGNORE_RESULT Literal str: >>> pl.lit("foo") # doctest: +IGNORE_RESULT Literal datetime: >>> from datetime import datetime >>> pl.lit(datetime(2021, 1, 20)) # doctest: +IGNORE_RESULT Literal Null: >>> pl.lit(None) # doctest: +IGNORE_RESULT Literal eager Series: >>> pl.lit(pl.Series("a", [1, 2, 3])) # doctest: +IGNORE_RESULT """ if isinstance(value, datetime): if in_nanoseconds_window(value): tu = "ns" else: tu = "ms" return (lit(_datetime_to_pl_timestamp( value, tu)).cast(Datetime).dt.and_time_unit(tu)) if isinstance(value, timedelta): if timedelta_in_nanoseconds_window(value): tu = "ns" else: tu = "ms" return (lit(_timedelta_to_pl_timedelta( value, tu)).cast(Duration).dt.and_time_unit(tu, dtype=Duration)) if isinstance(value, date): return lit(datetime(value.year, value.month, value.day)).cast(Date) if isinstance(value, pli.Series): name = value.name value = value._s e = pli.wrap_expr(pylit(value)) if name == "": return e return e.alias(name) if _NUMPY_AVAILABLE and isinstance(value, np.ndarray): return lit(pli.Series("", value)) if dtype: return pli.wrap_expr(pylit(value)).cast(dtype) # numpy literals like np.float32(0) # have an item if hasattr(value, "item"): value = value.item() # type: ignore[union-attr] return pli.wrap_expr(pylit(value))
def date_range( low: datetime, high: datetime, interval: Union[str, timedelta], closed: Optional[str] = "both", name: Optional[str] = None, time_unit: Optional[str] = None, ) -> "pli.Series": """ Create a date range of type `Datetime`. Parameters ---------- low Lower bound of the date range high Upper bound of the date range interval Interval periods A python timedelta object or a polars duration `str` e.g.: "3d12h4m25s" # 3 days, 12 hours, 4 minutes, and 25 seconds closed {None, 'left', 'right', 'both', 'none'} Make the interval closed to the 'left', 'right', 'none' or 'both' sides. name Name of the output Series time_unit Set the time unit; one of {'ns', 'ms'} Returns ------- A Series of type `Datetime` Examples -------- >>> from datetime import datetime >>> pl.date_range(datetime(1985, 1, 1), datetime(2015, 7, 1), "1d12h") shape: (7426,) Series: '' [datetime[ns]] [ 1985-01-01 00:00:00 1985-01-02 12:00:00 1985-01-04 00:00:00 1985-01-05 12:00:00 1985-01-07 00:00:00 1985-01-08 12:00:00 1985-01-10 00:00:00 1985-01-11 12:00:00 1985-01-13 00:00:00 1985-01-14 12:00:00 1985-01-16 00:00:00 1985-01-17 12:00:00 ... 2015-06-14 00:00:00 2015-06-15 12:00:00 2015-06-17 00:00:00 2015-06-18 12:00:00 2015-06-20 00:00:00 2015-06-21 12:00:00 2015-06-23 00:00:00 2015-06-24 12:00:00 2015-06-26 00:00:00 2015-06-27 12:00:00 2015-06-29 00:00:00 2015-06-30 12:00:00 ] """ if isinstance(interval, timedelta): interval = _timedelta_to_pl_duration(interval) if in_nanoseconds_window(low) and in_nanoseconds_window(high) and time_unit is None: tu = "ns" elif time_unit is not None: tu = time_unit else: tu = "ms" start = _datetime_to_pl_timestamp(low, tu) stop = _datetime_to_pl_timestamp(high, tu) if name is None: name = "" return pli.wrap_s(_py_date_range(start, stop, interval, closed, name, tu))
def lit( value: Optional[Union[float, int, str, date, datetime, "pli.Series"]], dtype: Optional[Type[DataType]] = None, ) -> "pli.Expr": """ A literal value. Parameters ---------- value Value that should be used as a `literal`. dtype Optionally define a dtype. Examples -------- Literal integer: >>> pl.lit(1) # doctest: +IGNORE_RESULT Literal str: >>> pl.lit("foo") # doctest: +IGNORE_RESULT Literal datetime: >>> from datetime import datetime >>> pl.lit(datetime(2021, 1, 20)) # doctest: +IGNORE_RESULT Literal Null: >>> pl.lit(None) # doctest: +IGNORE_RESULT Literal eager Series: >>> pl.lit(pl.Series("a", [1, 2, 3])) # doctest: +IGNORE_RESULT """ if isinstance(value, datetime): if in_nanoseconds_window(value): tu = "ns" else: tu = "ms" return (lit(_datetime_to_pl_timestamp( value, tu)).cast(Datetime).dt.and_time_unit(tu)) if isinstance(value, timedelta): if timedelta_in_nanoseconds_window(value): tu = "ns" else: tu = "ms" return (lit(_timedelta_to_pl_timedelta( value, tu)).cast(Duration).dt.and_time_unit(tu, dtype=Duration)) if isinstance(value, date): return lit(datetime(value.year, value.month, value.day)).cast(Date) if isinstance(value, pli.Series): name = value.name value = value._s return pli.wrap_expr(pylit(value)).alias(name) if isinstance(value, np.ndarray): return lit(pli.Series("", value)) if dtype: return pli.wrap_expr(pylit(value)).cast(dtype) return pli.wrap_expr(pylit(value))