Spec-Zone.ru › Polars

polars.DataFrame.join_asof

DataFrame.join_asof(
    other: DataFrame,
    *,
    left_on: str | None | Expr = None,
    right_on: str | None | Expr = None,
    on: str | None | Expr = None,
    by_left: str | Sequence[str] | None = None,
    by_right: str | Sequence[str] | None = None,
    by: str | Sequence[str] | None = None,
    strategy: AsofJoinStrategy = 'backward',
    suffix: str = '_right',
    tolerance: str | int | float | timedelta | None = None,
    allow_parallel: bool = True,
    force_parallel: bool = False,
    coalesce: bool = True,
    allow_exact_matches: bool = True,
    check_sortedness: bool = True,
) → DataFrame

Выполняет асоф-соединение.

Это похоже на левое соединение, за исключением того, что сопоставление выполняется по ближайшему ключу, а не по совпадающим ключам.

Оба DataFrame должны быть отсортированы по ключу on (внутри каждой группы by, если она указана).

Для каждой строки левого DataFrame:

  • Поиск «назад» выбирает последнюю строку правого DataFrame, ключ ‘on’ которой меньше или равен ключу левого DataFrame.
  • Поиск «вперёд» выбирает первую строку правого DataFrame, ключ ‘on’ которой больше или равен ключу левого DataFrame.
  • Поиск «ближайшего значения» выбирает последнюю строку правого DataFrame, значение которой ближе всего к ключу левого DataFrame. Строковые ключи в настоящее время не поддерживаются для поиска ближайшего значения.

По умолчанию используется поиск «назад».

Параметры:
other

Ленивый DataFrame для соединения.

left_on

Столбец соединения левого DataFrame.

right_on

Столбец соединения правого DataFrame.

on

Столбец соединения обоих DataFrame. Если задан, left_on и right_on должны иметь значение None.

by_left

Сначала выполнить соединение по этим столбцам, затем асоф-соединение

by_right

Сначала выполнить соединение по этим столбцам, затем асоф-соединение

by

Сначала выполнить соединение по этим столбцам, затем асоф-соединение

strategy{‘backward’, ‘forward’, ‘nearest’}

Стратегия соединения.

suffix

Суффикс, добавляемый к столбцам с повторяющимся именем.

tolerance

Числовой допуск. Если задать это значение, соединение будет выполнено, только если расстояние между близкими ключами не превышает его. Если асоф-соединение выполняется по столбцам типа “Date”, “Datetime”, “Duration” или “Time”, используйте объект datetime.timedelta или строку в следующем формате:

  • 1ns (1 наносекунда)
  • 1us (1 микросекунда)
  • 1ms (1 миллисекунда)
  • 1s (1 секунда)
  • 1m (1 минута)
  • 1h (1 час)
  • 1d (1 календарный день)
  • 1w (1 календарная неделя)
  • 1mo (1 календарный месяц)
  • 1q (1 календарный квартал)
  • 1y (1 календарный год)

Или объедините их: “3d12h4m25s” # 3 дня, 12 часов, 4 минуты и 25 секунд

Под «календарным днём» подразумевается соответствующее время следующего дня (который может длиться не 24 часа из-за перехода на летнее время; в неоднозначных случаях мы следуем RFC-5545 и сохраняем признак DST fold исходного объекта datetime). Аналогично для «календарной недели», «календарного месяца», «календарного квартала» и «календарного года».

allow_parallel

Разрешить физическому плану при необходимости параллельно вычислять оба DataFrame вплоть до этапа соединения.

force_parallel

Принудительно выполнять вычисления обоих DataFrame физическим планом параллельно вплоть до этапа соединения.

coalesce

Поведение объединения (слияние столбцов on / left_on / right_on):

  • True: Всегда объединять столбцы соединения.
  • False: Никогда не объединять столбцы соединения.

Обратите внимание: соединение по любым выражениям, кроме col, отключает объединение.

allow_exact_matches

Допускаются ли точные совпадения в условиях соединения.

  • If True, allow matching with the same on value

    (то есть «меньше или равно» / «больше или равно»)

  • If False, don’t match the same on value

    (то есть строго «меньше» / строго «больше»).

check_sortedness

Проверять сортировку ключей асоф-соединения. Если ключи не отсортированы, Polars выдаст ошибку. В настоящее время движок in-memory не может проверить сортировку, если указаны группы ‘by’. Движок streaming проверяет сортировку только обрабатываемых им строк.

См. также

join
join_where

Примеры

>>> from datetime import date
>>> gdp = pl.DataFrame(
...     {
...         "date": pl.date_range(
...             date(2016, 1, 1),
...             date(2020, 1, 1),
...             "1y",
...             eager=True,
...         ),
...         "gdp": [4164, 4411, 4566, 4696, 4827],
...     }
... )
>>> gdp
shape: (5, 2)
┌────────────┬──────┐
│ date       ┆ gdp  │
│ ---        ┆ ---  │
│ date       ┆ i64  │
╞════════════╪══════╡
│ 2016-01-01 ┆ 4164 │
│ 2017-01-01 ┆ 4411 │
│ 2018-01-01 ┆ 4566 │
│ 2019-01-01 ┆ 4696 │
│ 2020-01-01 ┆ 4827 │
└────────────┴──────┘
>>> population = pl.DataFrame(
...     {
...         "date": [date(2016, 3, 1), date(2018, 8, 1), date(2019, 1, 1)],
...         "population": [82.19, 82.66, 83.12],
...     }
... ).sort("date")
>>> population
shape: (3, 2)
┌────────────┬────────────┐
│ date       ┆ population │
│ ---        ┆ ---        │
│ date       ┆ f64        │
╞════════════╪════════════╡
│ 2016-03-01 ┆ 82.19      │
│ 2018-08-01 ┆ 82.66      │
│ 2019-01-01 ┆ 83.12      │
└────────────┴────────────┘

Обратите внимание, что даты не совсем совпадают. Если объединить их с помощью join_asof и strategy='backward', каждая дата из population, для которой нет точного совпадения, будет сопоставлена с ближайшей более ранней датой из gdp:

>>> population.join_asof(gdp, on="date", strategy="backward")
shape: (3, 3)
┌────────────┬────────────┬──────┐
│ date       ┆ population ┆ gdp  │
│ ---        ┆ ---        ┆ ---  │
│ date       ┆ f64        ┆ i64  │
╞════════════╪════════════╪══════╡
│ 2016-03-01 ┆ 82.19      ┆ 4164 │
│ 2018-08-01 ┆ 82.66      ┆ 4566 │
│ 2019-01-01 ┆ 83.12      ┆ 4696 │
└────────────┴────────────┴──────┘

Обратите внимание:

  • дата 2016-03-01 из population сопоставляется с 2016-01-01 из gdp;
  • дата 2018-08-01 из population сопоставляется с 2018-01-01 из gdp.

Это можно проверить, передав coalesce=False:

>>> population.join_asof(gdp, on="date", strategy="backward", coalesce=False)
shape: (3, 4)
┌────────────┬────────────┬────────────┬──────┐
│ date       ┆ population ┆ date_right ┆ gdp  │
│ ---        ┆ ---        ┆ ---        ┆ ---  │
│ date       ┆ f64        ┆ date       ┆ i64  │
╞════════════╪════════════╪════════════╪══════╡
│ 2016-03-01 ┆ 82.19      ┆ 2016-01-01 ┆ 4164 │
│ 2018-08-01 ┆ 82.66      ┆ 2018-01-01 ┆ 4566 │
│ 2019-01-01 ┆ 83.12      ┆ 2019-01-01 ┆ 4696 │
└────────────┴────────────┴────────────┴──────┘

Если вместо этого использовать strategy='forward', каждая дата из population, для которой нет точного совпадения, будет сопоставлена с ближайшей более поздней датой из gdp:

>>> population.join_asof(gdp, on="date", strategy="forward")
shape: (3, 3)
┌────────────┬────────────┬──────┐
│ date       ┆ population ┆ gdp  │
│ ---        ┆ ---        ┆ ---  │
│ date       ┆ f64        ┆ i64  │
╞════════════╪════════════╪══════╡
│ 2016-03-01 ┆ 82.19      ┆ 4411 │
│ 2018-08-01 ┆ 82.66      ┆ 4696 │
│ 2019-01-01 ┆ 83.12      ┆ 4696 │
└────────────┴────────────┴──────┘

Обратите внимание:

  • дата 2016-03-01 из population сопоставляется с 2017-01-01 из gdp;
  • дата 2018-08-01 из population сопоставляется с 2019-01-01 из gdp.

Наконец, strategy='nearest' даёт результат, сочетающий два предыдущих варианта: каждая дата из population, для которой нет точного совпадения, сопоставляется с ближайшей датой из gdp независимо от того, является ли она более ранней или более поздней:

>>> population.join_asof(gdp, on="date", strategy="nearest")
shape: (3, 3)
┌────────────┬────────────┬──────┐
│ date       ┆ population ┆ gdp  │
│ ---        ┆ ---        ┆ ---  │
│ date       ┆ f64        ┆ i64  │
╞════════════╪════════════╪══════╡
│ 2016-03-01 ┆ 82.19      ┆ 4164 │
│ 2018-08-01 ┆ 82.66      ┆ 4696 │
│ 2019-01-01 ┆ 83.12      ┆ 4696 │
└────────────┴────────────┴──────┘

Обратите внимание:

  • дата 2016-03-01 из population сопоставляется с 2016-01-01 из gdp;
  • дата 2018-08-01 из population сопоставляется с 2019-01-01 из gdp.

Аргумент by позволяет сначала выполнить соединение по другому столбцу, а затем асоф-соединение. В этом примере сначала выполняется соединение по country, а затем асоф-соединение по дате, как показано выше.

>>> gdp_dates = pl.date_range(  # fmt: skip
...     date(2016, 1, 1), date(2020, 1, 1), "1y", eager=True
... )
>>> gdp2 = pl.DataFrame(
...     {
...         "country": ["Germany"] * 5 + ["Netherlands"] * 5,
...         "date": pl.concat([gdp_dates, gdp_dates]),
...         "gdp": [4164, 4411, 4566, 4696, 4827, 784, 833, 914, 910, 909],
...     }
... ).sort("country", "date")
>>>
>>> gdp2
shape: (10, 3)
┌─────────────┬────────────┬──────┐
│ country     ┆ date       ┆ gdp  │
│ ---         ┆ ---        ┆ ---  │
│ str         ┆ date       ┆ i64  │
╞═════════════╪════════════╪══════╡
│ Germany     ┆ 2016-01-01 ┆ 4164 │
│ Germany     ┆ 2017-01-01 ┆ 4411 │
│ Germany     ┆ 2018-01-01 ┆ 4566 │
│ Germany     ┆ 2019-01-01 ┆ 4696 │
│ Germany     ┆ 2020-01-01 ┆ 4827 │
│ Netherlands ┆ 2016-01-01 ┆ 784  │
│ Netherlands ┆ 2017-01-01 ┆ 833  │
│ Netherlands ┆ 2018-01-01 ┆ 914  │
│ Netherlands ┆ 2019-01-01 ┆ 910  │
│ Netherlands ┆ 2020-01-01 ┆ 909  │
└─────────────┴────────────┴──────┘
>>> pop2 = pl.DataFrame(
...     {
...         "country": ["Germany"] * 3 + ["Netherlands"] * 3,
...         "date": [
...             date(2016, 3, 1),
...             date(2018, 8, 1),
...             date(2019, 1, 1),
...             date(2016, 3, 1),
...             date(2018, 8, 1),
...             date(2019, 1, 1),
...         ],
...         "population": [82.19, 82.66, 83.12, 17.11, 17.32, 17.40],
...     }
... ).sort("country", "date")
>>>
>>> pop2
shape: (6, 3)
┌─────────────┬────────────┬────────────┐
│ country     ┆ date       ┆ population │
│ ---         ┆ ---        ┆ ---        │
│ str         ┆ date       ┆ f64        │
╞═════════════╪════════════╪════════════╡
│ Germany     ┆ 2016-03-01 ┆ 82.19      │
│ Germany     ┆ 2018-08-01 ┆ 82.66      │
│ Germany     ┆ 2019-01-01 ┆ 83.12      │
│ Netherlands ┆ 2016-03-01 ┆ 17.11      │
│ Netherlands ┆ 2018-08-01 ┆ 17.32      │
│ Netherlands ┆ 2019-01-01 ┆ 17.4       │
└─────────────┴────────────┴────────────┘
>>> pop2.join_asof(gdp2, by="country", on="date", strategy="nearest")
shape: (6, 4)
┌─────────────┬────────────┬────────────┬──────┐
│ country     ┆ date       ┆ population ┆ gdp  │
│ ---         ┆ ---        ┆ ---        ┆ ---  │
│ str         ┆ date       ┆ f64        ┆ i64  │
╞═════════════╪════════════╪════════════╪══════╡
│ Germany     ┆ 2016-03-01 ┆ 82.19      ┆ 4164 │
│ Germany     ┆ 2018-08-01 ┆ 82.66      ┆ 4696 │
│ Germany     ┆ 2019-01-01 ┆ 83.12      ┆ 4696 │
│ Netherlands ┆ 2016-03-01 ┆ 17.11      ┆ 784  │
│ Netherlands ┆ 2018-08-01 ┆ 17.32      ┆ 910  │
│ Netherlands ┆ 2019-01-01 ┆ 17.4       ┆ 910  │
└─────────────┴────────────┴────────────┴──────┘

© 2020 Ritchie Vink
© 2022 Polars contributors
Licensed under the MIT License.
https://docs.pola.rs/api/python/stable/reference/dataframe/api/polars.DataFrame.join_asof.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API