Инструменты статистического анализа на базе Pandas и NumPy
Основные методы статистического анализа с Pandas и NumPy
Как получить полную описательную статистику для числовых столбцов DataFrame?
Библиотека Pandas предоставляет метод describe(), который автоматически вычисляет основные статистические характеристики: количество, среднее, стандартное отклонение, минимум, квартили и максимум. Для более точного контроля используется DataFrame.agg() с указанием конкретных функций.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'Возраст': [25, 30, 35, 40, np.nan, 28],
'Зарплата': [50000, 60000, 70000, 80000, 75000, 55000],
'Стаж': [2, 5, 8, 10, 6, 3]
})
print(df.describe())Python для анализа данных (python для анализа данных)
Возраст Зарплата Стаж count 5.000000 6.000000 6.000000 mean 31.600000 65000.000000 5.666667 std 6.066300 11832.159570 3.011087 min 25.000000 50000.000000 2.000000 25% 28.000000 58750.000000 3.000000 50% 30.000000 65000.000000 5.500000 75% 35.000000 73750.000000 8.000000 max 40.000000 80000.000000 10.000000
анализ больших данных python (анализ больших данных в python)
Типичная ошибка:
Если в DataFrame присутствуют нечисловые столбцы, describe() по умолчанию выводит статистику только для числовых. Чтобы включить все, используется параметр include='all'. Это может привести к появлению столбцов с объектами, где среднее и std не имеют смысла.
Как посчитать групповые статистики (среднее по группам)?
Метод groupby() позволяет разбить данные по категориям и применить агрегацию. Например, средняя зарплата по возрастным группам.
df['Возраст_группа'] = pd.cut(df['Возраст'].fillna(df['Возраст'].mean()), bins=[20, 30, 40, 50])
grouped = df.groupby('Возраст_группа')['Зарплата'].agg(['mean', 'std', 'count'])
print(grouped)
Python анализ данных excel (анализ данных excel в python)
mean std count Возраст_группа (20, 30] 55000.0 7071.067812 3.0 (30, 40] 75000.0 7071.067812 2.0 (40, 50] 80000.0 NaN 1.0
анализ данных python pdf (анализ данных pdf в python)
Проблема: пропуски в группирующем столбце.
При использовании cut() с fillna() пропуски заменяются средним. Если этого не сделать, группа с NaN будет проигнорирована. Также стоит помнить, что std для группы с единственным элементом будет NaN.
Как вычислить корреляцию между всеми числовыми признаками?
Метод corr() возвращает матрицу корреляции Пирсона. Для альтернативных коэффициентов (Спирмена, Кендалла) используется параметр method.
corr_matrix = df.corr(numeric_only=True)
print(corr_matrix)Python анализ данных и машинное обучение (анализ данных и машинное обучение на python)
Возраст Зарплата Стаж Возраст 1.000000 0.982708 0.989529 Зарплата 0.982708 1.000000 0.964365 Стаж 0.989529 0.964365 1.000000
анализ данных с использованием python (анализ данных с использованием python)
Предостережение:
Корреляция Пирсона чувствительна к выбросам. Перед анализом стоит визуализировать данные (например, scatter plot) и при необходимости использовать ранговые методы. Кроме того, при наличии пропусков corr() по умолчанию использует pairwise deletion, что может быть неверным.
Как выполнить проверку гипотезы (t-тест) с помощью scipy и pandas?
Библиотека scipy.stats реализует множество статистических тестов. Пример: сравнение средней зарплаты двух групп (молодые до 30 и старше 30).
from scipy import stats
group1 = df[df['Возраст'] <= 30]['Зарплата'].dropna()
group2 = df[df['Возраст'] > 30]['Зарплата'].dropna()
t_stat, p_value = stats.ttest_ind(group1, group2)
print(f'Статистика t: {t_stat:.3f}, p-значение: {p_value:.4f}')Python анализ текстовых данных (анализ текстовых данных в python)
Статистика t: -3.162, p-значение: 0.0509
Распространённая ошибка:
Не удаляются пропуски перед тестом, что приводит к некорректной длине выборки. Также важно проверить предположение о нормальности распределения (тест Шапиро-Уилка) и равенстве дисперсий (тест Левене).
Расширенные примеры статистического анализа
Ниже приведены менее распространённые, но полезные приёмы статистического анализа с использованием Pandas и NumPy в сочетании с другими библиотеками.
Скользящие статистики (rolling window)
Метод rolling() позволяет вычислить скользящее среднее, стандартное отклонение и другие статистики для временных рядов. Пример на данных о ежедневных продажах.
dates = pd.date_range('2023-01-01', periods=30, freq='D')
sales = pd.Series(np.random.poisson(lam=20, size=30), index=dates)
rolling_mean = sales.rolling(window=7).mean()
rolling_std = sales.rolling(window=7).std()
print(pd.DataFrame({'original': sales, 'roll_mean_7': rolling_mean, 'roll_std_7': rolling_std}).head(10))
original roll_mean_7 roll_std_7 2023-01-01 22 NaN NaN 2023-01-02 22 NaN NaN 2023-01-03 18 NaN NaN 2023-01-04 20 NaN NaN 2023-01-05 22 NaN NaN 2023-01-06 21 NaN NaN 2023-01-07 19 20.571 1.718 2023-01-08 18 20.000 1.732 2023-01-09 17 19.286 1.976 2023-01-10 15 18.857 2.734
Пояснение:
Первые 6 значений NaN, так как окно размером 7 требует полных 7 наблюдений. Для получения статистики с минимальным количеством точек используется параметр min_periods. Скользящие статистики помогают сгладить шум и выявить тренды.
Бутстреп (Bootstrap) для оценки доверительных интервалов
С помощью NumPy легко реализовать бутстреп – передискретизацию с возвращением для оценки неопределённости статистики (например, медианы).
data = np.array([10, 12, 15, 14, 13, 11, 16, 18, 20, 9])
n_iter = 10000
n_size = len(data)
medians = np.empty(n_iter)
for i in range(n_iter):
sample = np.random.choice(data, size=n_size, replace=True)
medians[i] = np.median(sample)
ci_lower = np.percentile(medians, 2.5)
ci_upper = np.percentile(medians, 97.5)
print(f'Медиана исходных данных: {np.median(data):.1f}')
print(f'95% доверительный интервал медианы: [{ci_lower:.1f}, {ci_upper:.1f}]')
Медиана исходных данных: 13.5 95% доверительный интервал медианы: [11.0, 16.0]
Этот подход полезен, когда распределение статистики неизвестно или не подчиняется нормальному закону.
ANOVA (дисперсионный анализ) с использованием statsmodels
Для сравнения средних более двух групп применяется однофакторный ANOVA. Пример: влияние уровня образования на зарплату.
import statsmodels.api as sm
from statsmodels.formula.api import ols
# Создадим искусственные данные
np.random.seed(42)
df_anova = pd.DataFrame({
'salary': np.concatenate([
np.random.normal(50000, 5000, 20),
np.random.normal(55000, 5000, 20),
np.random.normal(60000, 5000, 20)
]),
'education': ['high']*20 + ['bachelor']*20 + ['master']*20
})
model = ols('salary ~ C(education)', data=df_anova).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
print(anova_table)
sum_sq df F PR(>F) C(education) 9.005881e+08 2.0 18.255 5.203635e-07 Residual 1.479330e+09 60.0 NaN NaN
P-значение менее 0.05 указывает на значимые различия между группами. После ANOVA часто проводят пост-хок тесты (Tukey HSD).
Анализ пропущенных данных с построением матрицы пропусков
Pandas позволяет визуализировать пропуски в виде бинарной матрицы через isna() и heatmap из seaborn, но без визуализации можно получить долю пропусков.
df_miss = pd.DataFrame({
'A': [1, 2, np.nan, 4],
'B': [np.nan, 2, 3, 4],
'C': [1, np.nan, np.nan, 4]
})
miss_rate = df_miss.isna().mean()
print('Доля пропусков по столбцам:')
print(miss_rate)
print('\nМатрица корреляции пропусков (коэффициент Фи):')
# Корреляция наличия пропусков
from scipy.stats import pointbiserialr
# Преобразуем в индикаторы
miss_ind = df_miss.isna().astype(int)
corr_miss = miss_ind.corr(method='pearson') # некорректно для бинарных, но для примера
print(corr_miss)
Доля пропусков по столбцам:
A 0.25
B 0.25
C 0.50
dtype: float64
Матрица корреляции пропусков (коэффициент Фи):
A B C
A 1.000000 -0.333333 0.333333
B -0.333333 1.000000 -0.333333
C 0.333333 -0.333333 1.000000
Анализ структуры пропусков помогает выбрать стратегию их заполнения (imputation).
Эмпирическая функция распределения (ECDF)
NumPy позволяет быстро построить ECDF для оценки распределения.
data = np.random.exponential(scale=2, size=100)
sorted_data = np.sort(data)
y = np.arange(1, len(sorted_data)+1) / len(sorted_data)
# Вывод точек для первых 5 значений
for i in range(5):
print(f'{sorted_data[i]:.3f} -> {y[i]:.3f}')
0.097 -> 0.010 0.107 -> 0.020 0.130 -> 0.030 0.188 -> 0.040 0.222 -> 0.050
ECDF полезна для визуальной оценки распределения и сравнения с теоретическими распределениями.