Pandas знают все, помнят синтаксис — не все. Типичный вечер дата-саентиста: 30% — думать, 70% — гуглить, как сделать «то же самое, но через groupby с несколькими агрегатами». Claude Code забирает второй пункт полностью.
Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper
CLAUDE.md для анализа
## Стек - Python 3.11+, Jupyter - pandas 2.x, numpy - matplotlib + seaborn, plotly для интерактива - great_tables для красивых таблиц ## Правила - Никаких chained indexing `df[a][b]` — только `.loc[]` / `.iloc[]` - Копии явные: `df2 = df.copy()` когда мутируем - SettingWithCopyWarning — не игнорировать - Для больших данных — polars вместо pandas
Чистка данных
Типичный черновой датасет:
import pandas as pd
df = pd.read_csv("sales.csv")
df.info()
df.describe(include="all")
df.isna().sum().sort_values(ascending=False).head(20)Затем в Claude: «почисти датасет: удали дубликаты, заполни NaN в income медианой, приведи signup_date к datetime, отфильтруй age в диапазон 18-100».
# Дубликаты по ключу
df = df.drop_duplicates(subset=["user_id", "order_id"], keep="last")
# Типы
df["signup_date"] = pd.to_datetime(df["signup_date"], errors="coerce")
# NaN — медианой по группе
df["income"] = df.groupby("country")["income"].transform(
lambda s: s.fillna(s.median())
)
# Фильтр
df = df[df["age"].between(18, 100)]
# Проверка
assert df["signup_date"].isna().sum() == 0Groupby с несколькими агрегатами
summary = (
df.groupby(["country", "product_category"])
.agg(
orders=("order_id", "count"),
revenue=("amount", "sum"),
avg_ticket=("amount", "mean"),
unique_users=("user_id", "nunique"),
)
.reset_index()
.sort_values("revenue", ascending=False)
)С выводом в формате аналитика:
summary["revenue_pct"] = (
summary["revenue"] / summary["revenue"].sum() * 100
).round(2)Time series
Типичная задача: «конверсия по дням + 7-дневное скользящее среднее».
daily = (
df.assign(day=df["signup_date"].dt.date)
.groupby("day")
.agg(
signups=("user_id", "count"),
conversions=("converted", "sum"),
)
.reset_index()
)
daily["cr"] = daily["conversions"] / daily["signups"]
daily["cr_7d"] = daily["cr"].rolling(window=7, min_periods=3).mean()График:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 4))
ax.plot(daily["day"], daily["cr"], alpha=0.3, label="Daily")
ax.plot(daily["day"], daily["cr_7d"], linewidth=2, label="7-day MA")
ax.set_ylabel("Conversion rate")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("conversion.png", dpi=120)Merge без потерь
merged = users.merge(orders, on="user_id", how="left", indicator=True) # Проверка, сколько осталось без заказа print(merged["_merge"].value_counts()) # left_only 1204 # both 33921 # Проверка дубликатов после merge — если M:N случайно assert not merged.duplicated(subset=["user_id", "order_id"]).any()
indicator=True даёт колонку _merge — видно, какие строки с какой стороны.
Pivot table на аналитику
pivot = df.pivot_table(
index="country",
columns="month",
values="revenue",
aggfunc="sum",
fill_value=0,
margins=True,
margins_name="Total",
)Polars когда pandas мелкий
Для таблиц > 10 ГБ pandas начинает тормозить. Polars делает то же быстрее и параллельно:
import polars as pl
df = pl.scan_csv("huge_dataset.csv") # lazy
result = (
df.filter(pl.col("amount") > 0)
.group_by("country")
.agg([
pl.col("amount").sum().alias("revenue"),
pl.col("user_id").n_unique().alias("users"),
])
.sort("revenue", descending=True)
.collect() # выполнение только тут
)Подводные камни
- SettingWithCopyWarning. Обычно говорит «ты пишешь в view, а не в копию». Лечится
.copy()или.loc[]. - NaN в groupby. По умолчанию NaN-группы теряются.
dropna=Falseесли нужны. - Datetime без
errors="coerce". Один мусорный формат роняет весь парсинг. - Float для денег. Копейки теряются.
Decimalилиint64в копейках.
Как попробовать
1. Jupyter + CLAUDE.md 2. Загрузи свой CSV 3. Попроси: «почисти + посчитай CR по когортам» 4. Получи работающий ноутбук за 2-3 итерации
Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper
