Анализ данных в Python: возможности Pandas и NumPy
Основы анализа данных с Pandas и NumPy
Как эффективно получить первичное представление о данных и выявить аномалии?
Наиболее универсальным подходом для первоначального исследования данных (Exploratory Data Analysis, EDA) является комбинация методов Pandas и NumPy. Рассмотрим типовой сценарий: загрузка CSV-файла, базовый статистический обзор и обработка пропусков.
import pandas as pd
import numpy as np
# Загрузка данных
df = pd.read_csv('sales.csv')
# Первые строки
print(df.head())
# Базовая статистика
print(df.describe(include='all'))
# Информация о столбцах и типах
print(df.info())
Python для анализа данных (python для анализа данных)
Пояснение: pd.read_csv() читает данные, describe() выводит статистики (среднее, медиана, квартили), info() показывает количество непустых значений и типы. Это позволяет быстро оценить качество набора данных.
Типичные проблемы и их решения:
- Ошибка при загрузке: файл не найден или разделитель не совпадает. Указывайте полный путь или используйте
sep=';'для других разделителей. - Некорректное распознавание типов: столбец с датами может стать строкой. Примените
pd.to_datetime()после загрузки. - Пропущенные значения:
df.isnull().sum()покажет количество NaN. Заполнить их можноdf.fillna(value)или удалить строкиdf.dropna().
Как выполнить группировку и агрегацию для выявления закономерностей?
Группировка по категориям с последующей агрегацией - стандартный инструмент сводки данных. В Pandas это реализуется через groupby().
# Группировка по региону и аггрегация по сумме продаж
region_sales = df.groupby('region')['sales'].agg(['sum', 'mean', 'count'])
print(region_sales)
анализ больших данных python (анализ больших данных в python)
Пояснение: groupby('region') создаёт группы, ['sales'] выбирает интересующий столбец, .agg() применяет несколько функций. Результат - сводная таблица.
Возможные затруднения:
- Группировка по нескольким столбцам: передаётся список
groupby(['region', 'year']). - Агрегатная функция не срабатывает из-за нечисловых данных - используйте
pd.to_numeric()для принудительного преобразования.
Как обработать пропущенные значения с помощью NumPy?
NumPy предоставляет низкоуровневые инструменты для работы с массивами и пропусками (np.nan). Это полезно, когда требуется выполнить вычисления без использования Pandas.
arr = np.array([[1, 2, np.nan], [4, np.nan, 6], [7, 8, 9]])
# Замена NaN на среднее по столбцу
col_means = np.nanmean(arr, axis=0)
arr_filled = np.where(np.isnan(arr), col_means, arr)
print(arr_filled)
анализ данных python pdf (анализ данных pdf в python)
Пояснение: np.nanmean() игнорирует NaN при расчёте среднего, np.where() заменяет пропуски на вычисленные значения.
Распространённые ошибки:
- Использование
np.mean()вместоnp.nanmean()приведёт к результату NaN, если в данных есть пропуски. - Несоответствие размерностей при замене - необходимо убедиться, что
col_meansимеет ту же форму, что и ось, по которой производится замена.
Как применить функцию к каждой строке или столбцу (векторизация)?
Вместо медленных циклов в Pandas используется apply() или векторизированные операции NumPy. Для чистых числовых массивов NumPy работает значительно быстрее.
# Pandas apply (для демонстрации)
df['sales_with_tax'] = df['sales'].apply(lambda x: x * 1.2)
# Векторизированная операция NumPy (если данные в массиве)
prices = np.array([100, 200, 300])
prices_with_tax = prices * 1.2
print(prices_with_tax)
Python анализ данных и машинное обучение (анализ данных и машинное обучение на python)
Пояснение: apply() позволяет использовать произвольные функции, но при больших объёмах данных лучше перейти к векторным операциям NumPy.
Ошибки при использовании apply:
- Передача функции, которая возвращает Series для каждого элемента - это приводит к созданию лишних вложенных структур. Ожидается скалярное значение.
- Попытка изменить исходный DataFrame внутри apply - это не сработает, нужно присваивать результат.
Как создать сводную таблицу с несколькими индексами?
Метод pivot_table() в Pandas позволяет строить многомерные агрегации, аналогичные сводным таблицам Excel.
pivot = df.pivot_table(values='sales', index='region', columns='product', aggfunc='sum', fill_value=0)
print(pivot)
Пояснение: values - агрегируемый столбец, index - строки, columns - столбцы, aggfunc - функция агрегации, fill_value заменяет отсутствующие комбинации на 0.
Проблемы при построении сводной таблицы:
- Несколько значений в
indexилиcolumns- они должны быть переданы списком, но это может привести к перегрузке памяти при большом количестве уникальных значений. - Пропуски в данных -
fill_value=0не всегда уместен; иногда целесообразнее оставить NaN.
Расширенные примеры анализа данных с Pandas и NumPy
1. Работа с датами и временными рядами
Часто требуется преобразовать столбец с датами, выполнить выборку по временному диапазону или рассчитать скользящее среднее.
import pandas as pd
import numpy as np
# Создаём пример данных
dates = pd.date_range('2024-01-01', periods=10, freq='D')
sales = np.random.randint(100, 500, size=10)
df = pd.DataFrame({'date': dates, 'sales': sales})
# Установка индекса из дат
df.set_index('date', inplace=True)
# Выборка за определённый период
subset = df.loc['2024-01-03':'2024-01-07']
print(subset)
# Скользящее среднее за 3 дня
rolling_mean = df['sales'].rolling(window=3).mean()
print(rolling_mean)
Типичные ошибки:
- Неверный формат строки при преобразовании - используйте
pd.to_datetimeс параметромformat='%Y-%m-%d'для явного указания. - Пропуски в начале скользящего окна -
rolling()выдаёт NaN для первыхwindow-1значений, если не заданmin_periods.
2. Объединение данных (merge, join, concat)
При работе с несколькими источниками данных необходимо их объединять. Рассмотрим сценарий с таблицами пользователей и транзакций.
# Таблица пользователей
users = pd.DataFrame({
'user_id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie']
})
# Таблица транзакций
transactions = pd.DataFrame({
'user_id': [1, 2, 2, 3, 1],
'amount': [100, 200, 300, 400, 500],
'product': ['A', 'B', 'A', 'C', 'B']
})
# Внутреннее объединение по user_id
merged_inner = pd.merge(users, transactions, on='user_id', how='inner')
print(merged_inner)
# Левое объединение (все пользователи, даже без транзакций)
merged_left = pd.merge(users, transactions, on='user_id', how='left')
print(merged_left)
Результат (предположительно): user_id name amount product 0 1 Alice 100 A 1 1 Alice 500 B 2 2 Bob 200 B 3 2 Bob 300 A 4 3 Charlie 400 C
Проблемы при объединении:
- Неуникальные ключи -
mergeсоздаёт декартово произведение для повторяющихся значений, что может резко увеличить объём данных. - Разные имена столбцов: используйте параметры
left_onиright_on.
3. Использование MultiIndex (многоуровневые индексы)
MultiIndex позволяет организовать данные с несколькими уровнями иерархии, например, по году и месяцу.
arrays = [['2023', '2023', '2024', '2024'], ['Jan', 'Feb', 'Jan', 'Feb']]
index = pd.MultiIndex.from_arrays(arrays, names=['year', 'month'])
df_multi = pd.DataFrame({'sales': [100, 200, 150, 250]}, index=index)
print(df_multi)
# Доступ к данным по срезу
subset = df_multi.loc[('2023', 'Jan'):('2024', 'Feb')]
print(subset)
# Агрегация по одному из уровней
by_year = df_multi.groupby(level='year').sum()
print(by_year)
Результат для by_year:
sales
year
2023 300
2024 400
Ошибки при работе с MultiIndex:
- Срезы требуют указания всех уровней кортежа, иначе возникает
UnsortedIndexError. Сортировкаdf.sort_index()решает эту проблему. - Изменение значений через
locможет быть неинтуитивным - лучше обращаться по кортежам.
4. Векторизированные вычисления NumPy (Broadcasting)
NumPy позволяет выполнять операции над массивами разных размеров без явных циклов - это называется broadcasting.
import numpy as np
# Сложение матрицы и вектора
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
vector = np.array([10, 20, 30])
result = matrix + vector # вектор прибавляется к каждой строке
print(result)
# Умножение матрицы на столбец (через reshape)
col_vector = np.array([[10], [20]])
result2 = matrix * col_vector
print(result2)
Результат: [[11 22 33] [14 25 36]] [[10 20 30] [80 100 120]]
Типичные ошибки:
- Несовместимость форм - broadcasting работает только когда размерности совпадают или одна из них равна 1. Ошибка
ValueError: operands could not be broadcast together. - Использование
np.dotдля поэлементного умножения вместо*-np.dotвыполняет матричное умножение.
5. Обработка отсутствующих данных с продвинутыми методами
Иногда требуется интерполяция или заполнение на основе предыдущих/следующих значений.
import pandas as pd
import numpy as np
s = pd.Series([1, np.nan, np.nan, 4, np.nan, 6])
# Интерполяция по времени (если индекс временной)
s_interp = s.interpolate(method='time') # предполагается, что индекс - datetime
# Пример с линейной интерполяцией
s_linear = s.interpolate(method='linear')
print(s_linear)
# Заполнение по методу forward fill
s_ffill = s.ffill()
print(s_ffill)
Результат для s_linear: 0 1.000000 1 2.000000 2 3.000000 3 4.000000 4 5.000000 5 6.000000 dtype: float64
Проблемы интерполяции:
- При методе
timeтребуется, чтобы индекс былdatetimeи отсортирован; иначе результат неверен. - Большие серии пропусков подряд могут привести к экстраполяции, которая не всегда оправдана - стоит задать
limit.