Analiza i obliczanie KPI
Oblicz miesięczne utrzymanie kohort, przychody na poziomie produktu oraz kroczący 30-dniowy wskaźnik aktywnych użytkowników, używając groupby, pivot i rolling.
Analiza i obliczanie KPI to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Wczytywanie danych gotowych do analizy
Po zakończeniu czyszczenia i przygotowywania cech wczytaj punkt kontrolny analysis_ready.parquet i rozpocznij obliczanie KPI. Ten etap obejmuje wyłącznie analizę — dalsze czyszczenie danych nie jest już potrzebne. Czysty, zweryfikowany punkt kontrolny pozwala szybko iterować nad definicjami KPI bez ponownego wykonywania czasochłonnych etapów pozyskiwania i czyszczenia danych. Trzy KPI do obliczenia to: miesięczna retencja kohort, przychód produktów według kategorii oraz krocząca liczba aktywnych użytkowników z 30 dni.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
print(f'Loaded: {df.shape}')
print('KPIs to compute:')
print(' 1. Monthly cohort retention matrix')
print(' 2. Category revenue and margin ranking')
print(' 3. Rolling 30-day active users per region')KPI 1: Miesięczny przychód według kategorii
Pierwszym KPI jest miesięczny przychód według kategorii. Grupuj dane według year_month i category, sumuj przychód, a następnie wykonaj pivot, aby uzyskać kategorie jako kolumny, a miesiące jako wiersze. Ta tabela przestawna jest podstawą wykresu liniowego trendu oraz wykresu słupkowego najlepszych kategorii w raporcie. Zastosuj 3-miesięczną średnią kroczącą, aby wygładzić trend i uwidocznić sezonowość.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
# Monthly revenue by category
monthly_cat = (
df.groupby(['year_month', 'category'])['revenue']
.sum()
.reset_index()
.pivot(index='year_month', columns='category', values='revenue')
.fillna(0)
.sort_index()
)
# 3-month rolling average
monthly_cat_smooth = monthly_cat.rolling(3, min_periods=1).mean()
print('Monthly revenue by category (head):')
print(monthly_cat.round(0).head())
print('Shape:', monthly_cat.shape)KPI 2: Najlepsze regiony według łącznego przychodu
Uszereguj regiony według łącznego przychodu z całego okresu. Użyj groupby().agg(), aby jednocześnie obliczyć wiele statystyk: łączny przychód, liczbę zamówień, liczbę unikalnych klientów oraz średnią wartość zamówienia. Posortuj dane malejąco według łącznego przychodu i pozostaw 10 najlepszych regionów. Oblicz udział przychodu każdego regionu względem sumy całkowitej — ujawnia to ryzyko koncentracji (jeśli 80% przychodu pochodzi z jednego regionu, działalność firmy jest narażona na ryzyko geograficzne).
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
region_kpi = (
df.groupby('region')
.agg(
total_revenue=('revenue', 'sum'),
order_count=('order_id', 'nunique'),
unique_customers=('customer_id', 'nunique'),
avg_order_value=('revenue', 'mean')
)
.reset_index()
.sort_values('total_revenue', ascending=False)
)
total = region_kpi['total_revenue'].sum()
region_kpi['revenue_share'] = (region_kpi['total_revenue'] / total).round(3)
print(region_kpi.head(10).to_string(index=False))KPI 3: Macierz retencji kohort
Macierz retencji kohort pokazuje, jaki odsetek klientów z każdej kohorty pozyskania dokonał co najmniej jednego zakupu w każdym kolejnym okresie. Oblicz ją w trzech krokach: (1) przypisz każdemu zamówieniu „numer okresu” równy liczbie miesięcy od miesiąca kohorty klienta; (2) pogrupuj dane według kohorty i numeru okresu, a następnie policz unikalnych klientów; (3) podziel wynik przez rozmiar kohorty (liczbę klientów w okresie 0), aby uzyskać wskaźniki retencji. Wykonaj pivot do formatu kohorta × okres.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
# Compute months since cohort start
df['cohort_period'] = (
(df['order_date'].dt.to_period('M') -
pd.PeriodIndex(df['cohort_month'], freq='M'))
.apply(lambda x: x.n)
)
cohort_data = (
df.groupby(['cohort_month', 'cohort_period'])['customer_id']
.nunique()
.reset_index()
.rename(columns={'customer_id': 'customers'})
)
# Pivot: rows=cohort, columns=period
cohort_pivot = cohort_data.pivot(
index='cohort_month', columns='cohort_period', values='customers'
)
cohort_sizes = cohort_pivot[0]
retention = cohort_pivot.divide(cohort_sizes, axis=0).round(3)
print('Retention matrix (first 3 cohorts):')
print(retention.head(3))KPI 4: Krocząca liczba aktywnych użytkowników z 30 dni
Dzienna liczba aktywnych użytkowników (DAU) oraz jej warianty z oknem kroczącym to podstawowe KPI produktu. Oblicz liczbę unikalnych klientów, którzy dokonali zakupu w dowolnym 30-dniowym oknie. Najpierw oblicz dzienną liczbę unikalnych kupujących, ustaw datę jako indeks, a następnie zastosuj rolling('30D').apply(lambda x: x.nunique()) — pamiętaj jednak, że funkcja rolling dla DatetimeIndex wymaga określonej agregacji. Alternatywnie możesz użyć opartego na zbiorach kroczącego zliczania unikalnych wartości za pomocą niestandardowej funkcji okna.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
# Daily unique purchasers
daily = (
df.groupby('order_date')['customer_id']
.nunique()
.reset_index()
.rename(columns={'customer_id': 'daily_unique_customers'})
.set_index('order_date')
.sort_index()
)
# 30-day rolling sum (approximation: sum of daily unique purchasers)
# True rolling unique requires custom logic
daily['rolling_30d'] = daily['daily_unique_customers'].rolling('30D').sum()
print('Rolling 30-day active customers:')
print(daily.tail())Ranking przychodu na poziomie produktu
W analizie na poziomie produktu uszereguj wszystkie identyfikatory produktów według łącznego przychodu i oblicz ich skumulowany udział w przychodzie. Pozwala to sprawdzić, czy przychód ma rozkład Pareto (częsty wniosek: około 20% produktów generuje około 80% przychodu). Oblicz skumulowany przychód za pomocą .cumsum() i znajdź liczbę produktów wyznaczającą punkt odcięcia, w którym skumulowany udział przekracza 80%. Analiza ta pomaga podejmować decyzje dotyczące priorytetyzacji asortymentu produktów.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
product_rev = (
df.groupby('product_id')['revenue']
.sum()
.sort_values(ascending=False)
.reset_index()
)
total_rev = product_rev['revenue'].sum()
product_rev['rev_share'] = product_rev['revenue'] / total_rev
product_rev['cumulative_share'] = product_rev['rev_share'].cumsum()
pct80_cutoff = (product_rev['cumulative_share'] <= 0.80).sum()
total_products = len(product_rev)
print(f'Top {pct80_cutoff} of {total_products} products ({pct80_cutoff/total_products:.0%}) '
f'generate 80% of revenue (Pareto)')
print(product_rev.head())Zapisywanie wszystkich tabel KPI
Zapisz każdą tabelę KPI w osobnym pliku Parquet o nazwie zgodnej z konwencją w katalogu wyjściowym: kpi_{name}.parquet. Ułatwia to etap wizualizacji — odczytuje on dokładnie potrzebną, wcześniej obliczoną tabelę, bez ponownego wykonywania obliczeń. Zapisz również zbiorcze podsumowanie KPI w pliku CSV, aby łatwo udostępnić je nietechnicznym interesariuszom, którzy mogą otworzyć je w Excelu.
import pandas as pd
# Save all KPI tables
monthly_cat.to_parquet('output/kpi_monthly_category_revenue.parquet')
region_kpi.to_parquet('output/kpi_region_summary.parquet', index=False)
retention.to_parquet('output/kpi_cohort_retention.parquet')
daily.to_parquet('output/kpi_rolling_active_users.parquet')
product_rev.to_parquet('output/kpi_product_ranking.parquet', index=False)
# Also a CSV summary for sharing
region_kpi.to_csv('output/region_summary.csv', index=False)
print('All KPI tables saved:')
print(' kpi_monthly_category_revenue.parquet')
print(' kpi_region_summary.parquet')
print(' kpi_cohort_retention.parquet')
print(' kpi_rolling_active_users.parquet')
print(' kpi_product_ranking.parquet')Walidacja statystyczna KPI
Przed sfinalizowaniem KPI przeprowadź kontrole statystyczne: sprawdź za pomocą testu t dla jednej próby względem zerowego wzrostu, czy miesięczny wzrost przychodu jest istotny statystycznie, oraz za pomocą jednoczynnikowej analizy ANOVA sprawdź, czy różnice przychodu między regionami są istotne. Informacja o „najlepszym regionie według przychodu” ma większe znaczenie, gdy można potwierdzić, że różnica prawdopodobnie nie wynika z losowych wahań. Dołącz wartości p do tabel KPI jako kolumny metadanych.
import pandas as pd
import numpy as np
from scipy import stats
df = pd.read_parquet('output/analysis_ready.parquet')
# Is revenue growth statistically significant?
monthly_total = df.groupby('year_month')['revenue'].sum().sort_index()
month_changes = monthly_total.diff().dropna()
stat, p = stats.ttest_1samp(month_changes, popmean=0)
print(f'Monthly growth test: mean={month_changes.mean():.0f}, p={p:.4f}')
print('Significant positive trend?', month_changes.mean() > 0 and p < 0.05)
# ANOVA: do regions differ significantly?
groups = [g['revenue'].values for _, g in df.groupby('region')]
f, p_anova = stats.f_oneway(*groups)
print(f'Region ANOVA: F={f:.3f}, p={p_anova:.4f}')Obliczanie tempa wzrostu miesiąc do miesiąca
Tempo wzrostu miesiąc do miesiąca (MoM) jest podstawowym KPI biznesowym: growth = (current - previous) / previous × 100. Użyj pct_change(), aby przeprowadzić obliczenia w przejrzysty sposób. 3-miesięczna średnia krocząca wzrostu MoM pokazuje podstawowy trend, wygładzając miesięczne wahania. Ujemne tempo wzrostu jest równie ważne jak dodatnie i również należy je wyróżniać — sygnalizuje okresy wymagające zbadania.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
monthly_total = (
df.groupby('year_month')['revenue'].sum().sort_index()
)
growth = monthly_total.pct_change() * 100
trend = growth.rolling(3, min_periods=1).mean()
kpi_growth = pd.DataFrame({
'revenue': monthly_total,
'mom_growth_pct': growth.round(2),
'trend_3m_avg': trend.round(2)
})
print(kpi_growth.tail(6))
print(f'\nBest month: {monthly_total.idxmax()} (${monthly_total.max():,.0f})')
print(f'Worst month: {monthly_total.idxmin()} (${monthly_total.min():,.0f})')Automatyczne wykrywanie anomalii
Automatycznie oznaczaj anomalię miesięcy: miesiące, w których przychód różni się od średniej kroczącej z 6 miesięcy o więcej niż 2 odchylenia standardowe. Warto je zbadać — mogą odzwierciedlać rzeczywiste wydarzenia biznesowe (udaną kampanię, awarię danych) albo problemy z jakością danych (dwukrotne wczytanie zduplikowanych danych). Wykrywanie anomalii jest cennym dodatkiem do każdego zautomatyzowanego panelu monitorowania potoku danych i pomaga analitykom skupić analizę na najważniejszych okresach.
import pandas as pd
import numpy as np
df = pd.read_parquet('output/analysis_ready.parquet')
monthly = df.groupby('year_month')['revenue'].sum().sort_index()
rolling_mean = monthly.rolling(6, min_periods=3).mean()
rolling_std = monthly.rolling(6, min_periods=3).std()
anomalies = monthly[
(monthly > rolling_mean + 2 * rolling_std) |
(monthly < rolling_mean - 2 * rolling_std)
]
print('Anomalous months (>2 std from 6-month rolling mean):')
if len(anomalies) > 0:
print(anomalies.round(0))
else:
print('None detected')Tabela podsumowania KPI
Utwórz jedną tabelę podsumowania dla kadry kierowniczej, łączącą wartości najwyższego poziomu ze wszystkich KPI: łączny przychód, łączną liczbę zamówień, liczbę unikalnych klientów, średnią wartość zamówienia, najlepszy region, najlepszą kategorię oraz średnią 30-dniową retencję kohorty w 3. miesiącu. To jednotabelowe podsumowanie jest pierwszą stroną raportu — zapewnia interesariuszom natychmiastowy przegląd najważniejszych danych, zanim przejdą do wykresów i szczegółowych tabel.
import pandas as pd
df = pd.read_parquet('output/analysis_ready.parquet')
retention = pd.read_parquet('output/kpi_cohort_retention.parquet')
region_kpi = pd.read_parquet('output/kpi_region_summary.parquet')
summary = {
'Total Revenue': f'${df["revenue"].sum():,.0f}',
'Total Orders': f'{df["order_id"].nunique():,}',
'Unique Customers': f'{df["customer_id"].nunique():,}',
'Avg Order Value': f'${df["revenue"].mean():.2f}',
'Best Region': region_kpi.iloc[0]["region"],
'Best Category': df.groupby("category")["revenue"].sum().idxmax(),
'Avg Month-3 Retention': f'{retention.get(3, pd.Series([0])).mean():.1%}'
}
for k, v in summary.items():
print(f'{k:25s}: {v}')Szybki sprawdzian
Sprawdź swoją wiedzę na temat koncepcji analizy danych z tej lekcji.
Podsumowanie lekcji
W tej lekcji nauczyłeś się, że: groupby + pivot tworzy miesięczną macierz przychodów według kategorii oraz tabelę retencji kohort, rolling() oblicza wygładzone trendy i przybliżenia liczby aktywnych użytkowników w okresie 30 dni, a walidacja statystyczna (test t dla wzrostu, ANOVA dla różnic między regionami) zwiększa wiarygodność analizy KPI. W następnej części zwizualizujemy wszystkie wyniki na wielopanelowym wykresie i wyeksportujemy finalny raport.
Często zadawane pytania
Czy lekcja „Analiza i obliczanie KPI” jest bezpłatna?
Tak — pełny tekst „Analiza i obliczanie KPI” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Analiza i obliczanie KPI”?
Oblicz miesięczne utrzymanie kohort, przychody na poziomie produktu oraz kroczący 30-dniowy wskaźnik aktywnych użytkowników, używając groupby, pivot i rolling. Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?
Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Analiza i obliczanie KPI”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?
Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konfiguracja projektu i wczytywanie danych
- Czyszczenie danych i inżynieria cech
- Analiza i obliczanie KPI
- Końcowa wizualizacja i eksport raportu