Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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))
Example #6
0
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))
Example #7
0
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))