Перейти к основному содержимому

Pandas — объединение таблиц, своды и временные ряды

Разработчику

См. также: Анализ данных — обзор NumPy и Pandas · Даты и время · Классическое ML

Для кого эта глава

В обзорной статье разобраны NumPy, базовый Pandas и визуализация. Здесь — повседневные операции аналитика: точный выбор ячеек, соединение таблиц из разных источников, сводные отчёты и ряды по дате.

import pandas as pd

loc и iloc

МетодИндексация
ilocПо позиции (0, 1, 2 …), как в NumPy
locПо метке индекса и имени столбца
df = pd.DataFrame(
{"city": ["Москва", "Казань", "Москва"], "sales": [100, 50, 120]},
index=["a", "b", "c"],
)

df.loc["a", "sales"] # 100 — метка строки и столбца
df.iloc[0, 1] # 100 — первая строка, второй столбец
df.loc[df["city"] == "Москва", ["sales", "city"]]
df.iloc[0:2, :] # первые две строки, все столбцы

Срезы в loc включают правую границу ("a":"b" берёт и b). В iloc правая граница исключается — как в Python.

Присваивание через loc изменяет исходный фрейм (осторожно с SettingWithCopyWarning — работайте с .copy() при цепочках фильтров).


merge и join — склейка таблиц

Аналог SQL JOIN: два DataFrame по ключевым столбцам.

orders = pd.DataFrame({
"order_id": [1, 2, 3],
"user_id": [10, 10, 20],
"amount": [500, 300, 150],
})
users = pd.DataFrame({
"user_id": [10, 20],
"name": ["Анна", "Борис"],
})

pd.merge(orders, users, on="user_id", how="inner")
howРезультат
innerТолько совпадающие ключи
leftВсе строки левой таблицы
rightВсе строки правой
outerОбъединение с NaN где нет пары

Разные имена ключей: left_on="uid", right_on="user_id". Несколько ключей — список в on.

pd.concat([df1, df2], axis=0)стопка по строкам (одинаковые столбцы). axis=1 — добавление столбцов бок о бок по совпадающему индексу.


pivot_table и melt

Сводная таблица — агрегация по измерениям (как Excel pivot):

sales = pd.DataFrame({
"region": ["Север", "Север", "Юг", "Юг"],
"product": ["A", "B", "A", "B"],
"revenue": [100, 80, 120, 90],
})

pd.pivot_table(
sales,
values="revenue",
index="region",
columns="product",
aggfunc="sum",
fill_value=0,
)

melt («расплавление») переводит широкий формат в длинный — удобно перед визуализацией:

pd.melt(
wide_df,
id_vars=["id"],
value_vars=["jan", "feb"],
var_name="month",
value_name="amount",
)

Очистка — пропуски и дубликаты

df.dropna(subset=["email"]) # удалить строки без email
df.fillna({"age": df["age"].median()})
df.drop_duplicates(subset=["user_id"], keep="last")

Интерполяция по времени:

ts = df.set_index("date")["value"]
ts.interpolate(method="time")

Документируйте, почему выбран способ заполнения пропусков — это влияет на метрики и отчёты.


Временные ряды

df["date"] = pd.to_datetime(df["date"], format="%Y-%m-%d")
df = df.set_index("date").sort_index()

# срез по периоду
q1 = df.loc["2026-01":"2026-03"]

# ресемплинг — сумма по неделям
weekly = df["amount"].resample("W").sum()

# скользящее среднее за 7 дней
df["ma7"] = df["amount"].rolling(7).mean()

Часовые пояса: после pd.to_datetimedf.index.tz_localize("UTC") или tz_convert — подробнее в главе про datetime.


Производительность и границы

  • Операции над всей колонкой быстрее, чем apply по строкам в Python-цикле.
  • Для десятков гигабайт — Dask, Polars, Spark (см. обзор анализа данных).
  • Перед merge проверяйте дубликаты ключей — иначе строки размножатся.

Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).