Pandas & NumPy Academy · Урок

Объединение по индексу

Используйте DataFrame.join() и задавайте left_index/right_index=True в merge(), чтобы объединять DataFrames, выровненные по индексу.

Урок 4 из 413 шагов

«Объединение по индексу» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Объединения по индексу

До сих пор Вы объединяли DataFrames, сопоставляя значения в обычных столбцах. Но иногда нужная информация для сопоставления хранится в индексе DataFrame, а не в столбце. Pandas поддерживает объединения по индексу через DataFrame.join(), а также через pd.merge() с параметрами left_index=True или right_index=True.

Метод DataFrame.join()

DataFrame.join(other) — это вспомогательный метод, который по умолчанию объединяет по индексу обоих DataFrames. Он эквивалентен вызову pd.merge() с параметрами left_index=True, right_index=True. Тип объединения по умолчанию — 'left', в отличие от pd.merge(), где по умолчанию используется 'inner'. Для корректного результата оба DataFrame должны иметь содержательные метки индекса.

import pandas as pd

profiles = pd.DataFrame(
    {'age': [25, 30, 22]},
    index=['alice', 'bob', 'carol']
)

scores = pd.DataFrame(
    {'score': [88, 95, 70]},
    index=['alice', 'carol', 'dave']
)

# join: left join on index (default)
result = profiles.join(scores)
print(result)
#        age  score
# alice   25   88.0
# bob     30    NaN   <- bob has no score
# carol   22   95.0

Управление типом объединения в join()

Передайте параметр how в join(), чтобы управлять сохраняемыми строками, как и в pd.merge(). Доступны варианты 'left' (по умолчанию), 'right', 'inner' и 'outer'. Например, how='inner' сохраняет только индексы, присутствующие в обоих DataFrames, удаляя строку alice, если для неё нет соответствующего индекса в правой таблице.

# Inner join on index: only rows present in BOTH indices
print(profiles.join(scores, how='inner'))
#        age  score
# alice   25     88
# carol   22     70

# Outer join: all indices from both
print(profiles.join(scores, how='outer'))
#        age  score
# alice  25.0   88.0
# bob    30.0    NaN
# carol  22.0   70.0
# dave    NaN   95.0

Объединение нескольких DataFrames одновременно

Главное преимущество join() перед pd.merge() заключается в том, что он принимает список DataFrames и объединяет их с исходным DataFrame за один вызов. Все DataFrames должны быть выровнены по индексу. Это очень удобно, когда у Вас есть много таблиц признаков, проиндексированных одним и тем же ключом, например идентификатором пользователя или датой, и Вы хотите собрать их в один широкий DataFrame.

emails = pd.DataFrame({'email': ['a@x.com', 'b@x.com', 'c@x.com']},
                      index=['alice', 'bob', 'carol'])
city  = pd.DataFrame({'city': ['NY', 'LA', 'SF']},
                     index=['alice', 'bob', 'carol'])

# Join multiple DataFrames at once
result = profiles.join([emails, city])
print(result)
#        age    email city
# alice   25  a@x.com   NY
# bob     30  b@x.com   LA
# carol   22  c@x.com   SF

Объединение по столбцу одной таблицы и индексу другой

pd.merge() позволяет сочетать сопоставление по столбцу и по индексу с помощью left_on/right_index или left_index/right_on. Это полезно, когда один DataFrame хранит ключ в столбце, а другой использует его как индекс. С помощью одного только join() этого добиться нельзя.

# orders has customer_id as a column; customers is indexed by customer_id
customers_indexed = pd.DataFrame(
    {'name': ['Alice', 'Bob', 'Carol']},
    index=[101, 102, 103]
)
orders = pd.DataFrame({
    'order_id': [1, 2, 3],
    'customer_id': [101, 102, 101]
})

result = pd.merge(orders, customers_indexed,
                  left_on='customer_id', right_index=True)
print(result)
#    order_id  customer_id   name
# 0         1          101  Alice
# 2         3          101  Alice
# 1         2          102    Bob

Использование left_index и right_index в merge()

Если в обоих DataFrames ключ является индексом, используйте pd.merge(left, right, left_index=True, right_index=True). Это эквивалентно join(), но с типом объединения 'inner' по умолчанию и более явными параметрами. Кроме того, Вы получаете доступ ко всем остальным параметрам pd.merge(), таким как suffixes и indicator.

# Both DataFrames indexed by user_id
demog = pd.DataFrame({'age': [25, 30]}, index=[1, 2])
behav = pd.DataFrame({'clicks': [10, 5]}, index=[1, 2])

# Equivalent joins
result1 = demog.join(behav)  # left join
result2 = pd.merge(demog, behav, left_index=True, right_index=True)  # inner join

print(result1)
print(result2)

Зачем использовать объединения по индексу

Объединения по индексу предпочтительны, когда DataFrames естественным образом индексируются содержательным идентификатором, например идентификатором пользователя, артикулом товара SKU или датой. Использование индекса для объединений избавляет DataFrame от лишних столбцов ключей и может ускорить работу, поскольку Pandas поддерживает отсортированные структуры индексов для поиска за O(log n). Такие объединения особенно распространены во временных рядах, где DatetimeIndex является естественным ключом объединения.

# Time series example: join temperature and humidity by date index
import numpy as np
dates = pd.date_range('2024-01-01', periods=5)
temp = pd.DataFrame({'temp_c': [10, 12, 9, 11, 13]}, index=dates)
humid = pd.DataFrame({'humidity': [65, 70, 60, 75, 68]}, index=dates)

weather = temp.join(humid)
print(weather.head())

Обработка совпадающих имён столбцов

Если в обоих DataFrames есть столбцы с одинаковыми именами (кроме ключевого), join() по умолчанию вызывает ValueError, если не указать параметры lsuffix и rsuffix. Эти параметры работают подобно suffixes в pd.merge(), добавляя строку к совпадающим именам столбцов из левого и правого DataFrames соответственно.

df_a = pd.DataFrame({'value': [1, 2]}, index=['x', 'y'])
df_b = pd.DataFrame({'value': [10, 20]}, index=['x', 'y'])

# Without suffixes: raises ValueError
# result = df_a.join(df_b)

# With suffixes: disambiguate column names
result = df_a.join(df_b, lsuffix='_left', rsuffix='_right')
print(result)
#    value_left  value_right
# x           1           10
# y           2           20

set_index перед объединением

Распространённый рабочий процесс — назначить столбец индексом перед объединением, чтобы использовать синтаксис join(). После объединения reset_index() возвращает ключ в обычный столбец. Этот шаблон естественно читается: преобразовать ключ в индекс, выполнить объединение, вернуть ключ из индекса, — благодаря чему замысел кода понятен будущим читателям.

orders_col = pd.DataFrame({'order_id': [1,2,3], 'customer_id': [10,20,10], 'amount': [100,200,150]})
cust_col = pd.DataFrame({'customer_id': [10,20], 'name': ['Alice','Bob']})

result = (
    orders_col.set_index('customer_id')
    .join(cust_col.set_index('customer_id'), how='left')
    .reset_index()
)
print(result)

Выравнивание Series по индексу DataFrame

У Series также есть индекс, и его можно добавить в DataFrame как новый столбец с помощью присваивания — Pandas автоматически сопоставит значения Series с соответствующими метками индекса. Это облегчённый вариант объединения по индексу, который подходит, когда нужно добавить один столбец из Series без вызова merge() или join().

df = pd.DataFrame({'sales': [100, 200, 150]}, index=['A', 'B', 'C'])
tax_rate = pd.Series({'A': 0.1, 'B': 0.2, 'C': 0.15})

# Index alignment: Series aligns to DataFrame index automatically
df['tax'] = df['sales'] * tax_rate
print(df)
#    sales   tax
# A    100  10.0
# B    200  40.0
# C    150  22.5

Производительность объединения по индексу

Объединение по отсортированному индексу выполняется быстрее, чем объединение по обычному столбцу, поскольку Pandas использует двоичный поиск по отсортированному индексу. Если Вы неоднократно объединяете данные по одному и тому же ключу, установите этот ключ в качестве индекса один раз в начале конвейера обработки. Это особенно важно при работе с временными рядами, когда объединение по DatetimeIndex выполняется тысячи раз для множества файлов.

# Sort index before repeated joins for speed
left = left.sort_index()
right = right.sort_index()

# Both sorted -> Pandas uses merge path with binary search
result = left.join(right, how='inner')

# Check if index is sorted
print('Left sorted:', left.index.is_monotonic_increasing)
print('Right sorted:', right.index.is_monotonic_increasing)

Быстрая проверка

Проверьте, насколько хорошо Вы поняли объединение по индексу из этого урока.

Итоги урока

В этом уроке Вы узнали, что DataFrame.join() по умолчанию объединяет данные по индексу с использованием левого объединения; pd.merge() с параметрами left_index=True/right_index=True предоставляет больше возможностей для управления; несколько DataFrames можно объединить одновременно, передав список в join(); а использование отсортированного индекса повышает производительность объединения. Далее мы рассмотрим изменение формы DataFrames с помощью pivot_table.

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «Объединение по индексу» бесплатный?

Да — полный текст урока «Объединение по индексу» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Чему я научусь в уроке «Объединение по индексу»?

Используйте DataFrame.join() и задавайте left_index/right_index=True в merge(), чтобы объединять DataFrames, выровненные по индексу. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?

Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Объединение по индексу»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?

Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. pd.concat для объединения DataFrames
  2. pd.merge: внутреннее и внешнее объединение
  3. Левое и правое объединение
  4. Объединение по индексу
← Назад к Pandas & NumPy Academy