Выбор данных из MultiIndex
Получайте данные на внешнем и внутреннем уровнях индекса с помощью .loc, используя кортежи, срезы и вспомогательный объект pd.IndexSlice.
«Выбор данных из MultiIndex» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Навигация по иерархическим данным
После создания MultiIndex Вам понадобятся эффективные способы извлечения подмножеств данных. Pandas предоставляет для этого три инструмента: .loc с кортежами для точного выбора по метке, slice() и pd.IndexSlice для выбора диапазона по уровням и .xs() для выбора поперечного среза по значению определённого уровня. Освоив эти способы доступа, Вы раскроете все возможности иерархической индексации.
import pandas as pd
import numpy as np
# Setup: GDP data by country and year
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK','DE','DE','DE'],
'year': [2021, 2022, 2023, 2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200, 4100, 4200, 4350]
})
df = df_flat.set_index(['country', 'year']).sort_index()
print(df)Выбор по внешнему уровню с помощью .loc
Передайте в .loc[] одну метку внешнего уровня, чтобы получить все строки этой группы. Для двухуровневого MultiIndex (страна, год) выражение df.loc['USA'] возвращает все строки USA в виде DataFrame, в котором остаётся только внутренний индекс (год). Такое поведение называется удалением уровня: при выборе конкретного значения внешнего уровня Pandas удаляет этот уровень из индекса возвращаемого объекта.
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK'],
'year': [2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Select all USA rows
usa = df.loc['USA']
print('All USA rows:')
print(usa)
print('\nRemaining index type:', usa.index.name)Выбор конкретного кортежа с помощью .loc
Чтобы получить одну строку, определяемую обоими уровнями индекса, передайте кортеж в .loc[]: df.loc[('USA', 2022)]. Это возвращает Series (или скаляр для одного столбца), соответствующий ровно этой комбинации меток (внешняя, внутренняя). Если Вы хотите получить DataFrame, а не Series, кортеж необходимо передать внутри списка: df.loc[[('USA', 2022)]].
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','USA','UK','UK','UK'],
'year': [2021, 2022, 2023, 2021, 2022, 2023],
'gdp_bn': [23000, 25000, 26000, 3000, 3100, 3200],
'cpi': [3.2, 5.1, 4.8, 2.5, 3.4, 3.0]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Single row as Series
print('USA 2022 (Series):')
print(df.loc[('USA', 2022)])
# Single row as DataFrame
print('\nUSA 2022 (DataFrame):')
print(df.loc[[('USA', 2022)]])Выбор нескольких строк с помощью списка кортежей
Чтобы одновременно выбрать несколько конкретных строк, передайте в .loc[] список кортежей. Это удобно, когда нужен разрозненный набор строк, определяемых составными ключами, — например, данные за 2022 год для USA и UK, но не для Германии. В результате MultiIndex сохраняется в возвращённом DataFrame.
import pandas as pd
df_flat = pd.DataFrame({
'country': ['USA','USA','UK','UK','DE','DE'],
'year': [2022, 2023, 2022, 2023, 2022, 2023],
'gdp_bn': [25000, 26000, 3100, 3200, 4200, 4350]
})
df = df_flat.set_index(['country', 'year']).sort_index()
# Select specific (country, year) combinations
subset = df.loc[[('USA', 2022), ('UK', 2023), ('DE', 2022)]]
print(subset)Срезы с помощью pd.IndexSlice
pd.IndexSlice (обычно обозначаемый псевдонимом idx) позволяет задавать срезы диапазонов для уровней MultiIndex без ручного создания громоздких кортежей срезов. Синтаксис: df.loc[idx[outer_slice, inner_slice], column_slice]. Например, df.loc[idx['UK':'USA', 2022:2023], :] выбирает все строки, в которых внешний уровень находится между UK и USA, а внутренний — между 2022 и 2023 годами. Для корректной работы индекс должен быть отсортирован.
import pandas as pd
import numpy as np
years = [2021, 2022, 2023]
countries = ['DE', 'UK', 'USA']
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': np.random.randint(3000, 26000, 9)}, index=mi)
idx = pd.IndexSlice
# Select UK and USA for years 2022 and 2023
subset = df.loc[idx['UK':'USA', 2022:2023], :]
print(subset)Доступ к поперечному срезу с помощью .xs()
df.xs(key, level=) выбирает все строки, в которых определённый уровень равен заданному значению, независимо от содержимого остальных уровней. В отличие от .loc, которому сначала нужно указать внешние уровни, .xs позволяет напрямую обратиться к любому уровню по имени. Например, df.xs(2022, level='year') возвращает все строки за 2022 год для всех стран без необходимости указывать 'USA', 'UK' или 'DE'.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000]}, index=mi)
# All countries for year 2022 (inner level)
print('All data for year 2022:')
print(df.xs(2022, level='year'))
# All years for UK (outer level)
print('\nAll years for UK:')
print(df.xs('UK', level='country'))Доступ к столбцам MultiIndex
Если DataFrame имеет MultiIndex у столбцов, используйте кортежи для доступа к конкретным столбцам: df[('revenue', 'Q1')]. Чтобы выбрать все столбцы внешнего уровня (например, все столбцы выручки), используйте df['revenue'] — это вернёт DataFrame со всеми столбцами внутреннего уровня, относящимися к этому внешнему ключу. Шаблон с pd.IndexSlice также работает с многоуровневыми индексами столбцов в сочетании с .loc.
import pandas as pd
import numpy as np
metrics = ['revenue', 'cost']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
cols = pd.MultiIndex.from_product([metrics, quarters], names=['metric', 'quarter'])
df = pd.DataFrame(
np.random.randint(50, 200, (3, 8)),
columns=cols,
index=['USA', 'UK', 'DE']
)
# Access all revenue columns
print('Revenue columns:')
print(df['revenue'])
# Access a specific cell
print('\nUSA revenue Q1:', df.loc['USA', ('revenue', 'Q1')])Выбор внутреннего уровня для всех внешних ключей
Чтобы выбрать одно значение внутреннего уровня для всех значений внешнего уровня, объедините .loc со значением slice(None) для внешнего уровня: df.loc[(slice(None), 2022), :]. Это выбирает строку за 2022 год для каждой страны. Вариант с pd.IndexSlice читается понятнее: df.loc[idx[:, 2022], :]. Такой шаблон часто нужен, когда требуется получить снимок всех объектов на определённый момент времени.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000]}, index=mi)
idx = pd.IndexSlice
# All countries for year 2022 (using IndexSlice)
all_2022 = df.loc[idx[:, 2022], :]
print('All countries in 2022:')
print(all_2022)Распространённые ошибки при выборе данных из MultiIndex
Три распространённые ошибки: 1) Несортированный индекс: срез несортированного MultiIndex вызывает UnsortedIndexError или возвращает неверные результаты — всегда сначала вызывайте sort_index(). 2) KeyError при использовании кортежа в качестве ключа: если передать кортеж без обёртки в .loc[], Python интерпретирует его как позиционную индексацию — для доступа к MultiIndex по меткам всегда используйте .loc. 3) Несоответствие уровней: после groupby имена уровней MultiIndex могут отличаться от ожидаемых — проверьте df.index.names перед созданием среза.
import pandas as pd
# Unsorted MultiIndex slicing
tuples = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi = pd.MultiIndex.from_tuples(tuples, names=['letter', 'num'])
df = pd.DataFrame({'value': [10, 20, 30, 40]}, index=mi)
print('Is sorted:', df.index.is_monotonic_increasing)
# Sort before slicing
df = df.sort_index()
print('After sort:', df.index.is_monotonic_increasing)
idx = pd.IndexSlice
print('\nSlice A:')
print(df.loc[idx['A', :], :])Практический пример: квартальная отчётность
Рассмотрим практический случай: у Вас есть данные о продажах с индексом (регион, квартал), и для отчёта за год нужно извлечь Q4 по всем регионам. Используйте .xs('Q4', level='quarter'), чтобы получить этот поперечный срез одним вызовом. Затем вычислите итог с помощью .sum(). Такой шаблон — агрегация через groupby → результат с MultiIndex → извлечение поперечного среза — чрезвычайно распространён в конвейерах подготовки бизнес-отчётности.
import pandas as pd
import numpy as np
regions = ['North', 'South', 'East', 'West']
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
mi = pd.MultiIndex.from_product([regions, quarters], names=['region', 'quarter'])
np.random.seed(42)
df = pd.DataFrame({
'sales': np.random.randint(200, 500, 16),
'units': np.random.randint(50, 150, 16)
}, index=mi)
# Extract Q4 performance across all regions
q4 = df.xs('Q4', level='quarter')
print('Q4 Results by Region:')
print(q4)
print('\nQ4 Total Sales:', q4['sales'].sum())Объединение выбора из MultiIndex со столбцами
Вы можете одновременно выбрать конкретные строки и столбцы с помощью .loc[row_indexer, column_list]. При работе с MultiIndex индексатором строк может быть кортеж, список кортежей или IndexSlice, а индексатором столбцов — имя столбца или список имён. Это позволяет одним выражением извлечь точную прямоугольную подтаблицу из иерархического DataFrame.
import pandas as pd
import numpy as np
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({
'gdp': [4100,4200,4350, 3000,3100,3200, 23000,25000,26000],
'inflation': [1.5, 2.1, 2.8, 2.0, 3.4, 2.9, 3.2, 5.1, 4.8],
'unemployment': [5.0, 4.8, 4.5, 4.5, 4.2, 4.0, 3.8, 3.5, 3.3]
}, index=mi)
idx = pd.IndexSlice
# UK and USA, years 2022-2023, only gdp and inflation
result = df.loc[idx['UK':'USA', 2022:2023], ['gdp', 'inflation']]
print(result)Быстрая проверка
Проверьте, насколько хорошо Вы поняли выбор данных из MultiIndex в этом уроке.
Итоги урока
В этом уроке Вы узнали, как использовать .loc с кортежами для выбора конкретных сочетаний меток (внешняя, внутренняя), pd.IndexSlice — для создания срезов диапазонов на любых уровнях, а .xs() — для извлечения поперечного среза на любом уровне независимо от внешних ключей. Всегда сначала сортируйте индекс, чтобы избежать UnsortedIndexError. Далее мы рассмотрим выравнивание индексов и переиндексацию — то, как Pandas выравнивает два DataFrames по общему индексу.
Часто задаваемые вопросы
Урок «Выбор данных из MultiIndex» бесплатный?
Да — полный текст урока «Выбор данных из MultiIndex» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Чему я научусь в уроке «Выбор данных из MultiIndex»?
Получайте данные на внешнем и внутреннем уровнях индекса с помощью .loc, используя кортежи, срезы и вспомогательный объект pd.IndexSlice. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?
Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Выбор данных из MultiIndex»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?
Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Создание MultiIndex
- Выбор данных из MultiIndex
- Выравнивание и переиндексация
- Преимущества отсортированных индексов