Pandas MultiIndex

MultiIndex — это мощная функция индексации в Pandas, позволяющая создавать многоуровневые иерархические структуры для строк или столбцов. Это особенно полезно при работе с многомерными данными, групповой статистикой и панельными данными.


Создание MultiIndex

Создание из списка

Пример

import pandas as pd

# Способ 1: Создание с помощью массивов
arrays = [
    ["A", "A", "B", "B", "C", "C"],
    [1, 2, 1, 2, 1, 2]
]

# Использование pd.MultiIndex.from_arrays
index = pd.MultiIndex.from_arrays(arrays, names=["Категория", "Номер"])
print("Создано из массивов:")
print(index)
print()

# Способ 2: Использование списка кортежей
tuples = [
    ("A", 1), ("A", 2), ("B", 1), ("B", 2), ("C", 1), ("C", 2)
]
index = pd.MultiIndex.from_tuples(tuples, names=["Категория", "Номер"])
print("Создано из кортежей:")
print(index)
print()

# Способ 3: Использование произведения
index = pd.MultiIndex.from_product(
    [["A", "B", "C"], [1, 2, 3]],
    names=["Категория", "Номер"]
)
print("Создано из продукта:")
print(index)

Создание DataFrame с MultiIndex

Пример

import pandas as pd
import numpy as np

# Создание DataFrame с MultiIndex
df = pd.DataFrame(
    np.random.randn(6, 4),
    index=pd.MultiIndex.from_tuples(
        [("2024", "Q1"), ("2024", "Q2"), ("2024", "Q3"),
         ("2025", "Q1"), ("2025", "Q2"), ("2025", "Q3")]
    ),
    columns=["Пекин", "Шанхай", "Гуанчжоу", "Шэньчжэнь"]
)
df.index.names = ["Год", "Квартал"]

print("DataFrame с MultiIndex:")
print(df)

Доступ к MultiIndex

Доступ с помощью loc/iloc

Пример

import pandas as pd

# Создание образца данных
df = pd.DataFrame({
    "Китайский": [85, 92, 78, 88],
    "Математика": [90, 88, 95, 82]
}, index=pd.MultiIndex.from_tuples(
    [("10 класс", "Класс A"), ("10 класс", "Класс B"), ("11 класс", "Класс A"), ("11 класс", "Класс B")],
    names=["Grade", "Class"]
))

print("Исходные данные:")
print(df)
print()

# Доступ к внешнему индексу
print("Доступ ко всем Grade 10:")
print(df.loc["Grade 10"])
print()

# Доступ к внутреннему индексу
print("Доступ к Class A:")
print(df.loc[:, "Class A"])
print()

# Доступ к нескольким уровням индекса
print("Доступ к Class A в Grade 10:")
print(df.loc[("Grade 10", "Class A")])

Доступ с использованием xs

Пример

import pandas as pd

# Создание образца данных
df = pd.DataFrame({
    "Китайский": [85, 92, 78, 88],
    "Математика": [90, 88, 95, 82]
}, index=pd.MultiIndex.from_tuples(
    [("10 класс", "Класс A"), ("10 класс", "Класс B"), ("11 класс", "Класс A"), ("11 класс", "Класс B")],
    names=["Grade", "Class"]
))

# Использование xs для доступа к значениям на определённом уровне
print("Доступ к Grade 10 с использованием xs:")
print(df.xs("Grade 10", level="Grade"))
print()

print("Доступ к Class A с помощью xs:")
print(df.xs("Class A", level="Class"))

Преобразование MultiIndex

Стекинг и анстекинг

Пример

import pandas as pd
import numpy as np

# Создание DataFrame в широком формате
df = pd.DataFrame(
    np.arange(12).reshape(3, 4),
    index=pd.MultiIndex.from_tuples(
        [("Beijing", "2024"), ("Shanghai", "2024"), ("Guangzhou", "2024")]
    ),
    columns=pd.MultiIndex.from_tuples(
        [("Q1", "Revenue"), ("Q1", "Profit"), ("Q2", "Revenue"), ("Q2", "Profit")]
    )
)

print("Исходные данные (вложенные столбцы):")
print(df)
print()

# unstack: Преобразовать внутренний индекс в столбцы
df_unstacked = df.unstack()
print("После unstack:")
print(df_unstacked)
print()

# stack: Преобразовать столбцы во внутренний индекс
df_stacked = df_unstacked.stack()
print("После stack:")
print(df_stacked)

Сортировка MultiIndex

Пример

import pandas as pd

# Создание DataFrame с несортированным индексом
df = pd.DataFrame({
    "Значение": [1, 2, 3, 4, 5, 6]
}, index=pd.MultiIndex.from_tuples(
    [("C", 2), ("A", 1), ("B", 2), ("A", 2), ("C", 1), ("B", 1)],
    names=["Буква", "Число"]
))

print("Несортированные данные:")
print(df)
print()

# Сортировка по внешнему уровню
df_sorted1 = df.sort_index()
print("После сортировки по внешнему уровню:")
print(df_sorted1)
print()

# Сортировка по внутреннему уровню
df_sorted2 = df.sort_index(level=1)
print("После сортировки по внутреннему уровню:")
print(df_sorted2)
print()

# Сортировка по нескольким уровням
df_sorted3 = df.sort_index(level=[0, 1])
print("После сортировки по нескольким уровням:")
print(df_sorted3)

Практика: Групповая статистика

MultiIndex очень хорошо подходит для групповой статистики и сводного анализа.

Пример

import pandas as pd
import numpy as np

# Создание данных о продажах
np.random.seed(42)
df = pd.DataFrame({
    "Year": ["2023"] * 6 + ["2024"] * 6,
    "Quarter": ["Q1", "Q2", "Q3", "Q4"] * 3,
    "Товар": ["Телефон", "Телефон", "Компьютер", "Компьютер"] * 3,
    "Регион": ["Восточный Китай", "Южный Китай", "Северный Китай"] * 4,
    "Сумма продаж": np.random.randint(100, 500, 12)
})

print("Исходные данные о продажах:")
print(df)
print()

# Настройка MultiIndex и выполнение групповой статистики
df_grouped = df.set_index(["Год", "Квартал", "Товар", "Регион"])
print("Сгруппировано по году, кварталу, товару, региону:")
print(df_grouped)

# Сводка по годам
yearly = df_grouped.groupby(level="Год").sum()
print("\n"Годовые продажи:")
print(yearly)

# Сводка по годам и кварталам
quarterly = df_grouped.groupby(level=["Year", "Quarter"]).sum()
print("\n"Квартальные продажи:")
print(quarterly)

Типичные проблемы и примечания

1. Путаница с уровнями индекса

Будьте осторожны при операциях с данными, чтобы не перепутать уровни. Рекомендуется проверять до и после операций.df.index.names。

2. Ошибки доступа к индексу

locИспользуйте доступ по меткам,ilocИспользуйте доступ по позиции; не смешивайте эти два способа.

3. Дублирующийся индекс при использовании concat

При использованииconcatпри объединении данных дублирующиеся индексы могут привести к неожиданным результатам. Вы можете использоватьignore_index=Trueдля сброса.

MultiIndex — это ключевая возможность Pandas для работы с многомерными данными. Правильное использование MultiIndex делает организацию данных более чистой, а статистику — более удобной.

Другие расширения