Операции с датафреймами/сериями

Математические функции и статистика

В панде уже реализовано множество математических функций для работы с данными, уже сохраненными в соответствующей структуре данных. Весь их список стоит посмотреть по ссылкам на общей странице (раздел «Внешняя документация») Рассмотрим некоторые из них.

Функция mean() без параметра (0 или столбцы подразумевается по-умолчанию) вычисляет среднее значение для каждого столбца датафрейма

df.mean()

Если указать параметр 1, то вычислено будет среднее значение по строке

df.mean(1)

abs() - берет модуль от каждого элемента

count() - считает количество существующих (которые не равны NaN) элементов

max()/min() - находят максимум и минимум

sum()/prod() - сумма или произведение

Применение функции к элементам структуры

С помощью функции apply() можно применить заданную функцию ко всей структуре сразу.

Например, создадим следующий датафрейм

df = pd.DataFrame([[4, 9],] * 3, columns=['A', 'B'])

A B
0 4 9
1 4 9
2 4 9

Извлечем корень из каждого элемента таблицы

df.apply(np.sqrt) # здесь мы пользуемся функцией квадратного корня из библиотеки numpy, обратите внимание, что в этом контексте скобки не нужны

A B
0 2.0 3.0
1 2.0 3.0
2 2.0 3.0

Функцию можно применить и ко всему столбцу

df.apply(np.sum, axis=0)

или строке

df.apply(np.sum, axis=1)

Группировка

Группировкой будем считать один или несколько следующих шагов:

Разделение данных на группы по какому-нибудь критерию

Применение функции независимо к каждой группе

Комбинирование результатов в общую структуру

Посмотрим на примеры:

Создадим датафрейм

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : np.random.randn(8), 'D' : np.random.randn(8)}) print(df)

A B C D
0 foo one -1.202872 -0.055224
1 bar one -1.814470 2.395985
2 foo two 1.018601 1.552825
3 bar three -0.595447 0.166599
4 foo two 1.395433 0.047609
5 bar two -0.392670 -0.136473
6 foo one 0.007207 -0.561757
7 foo three 1.928123 -1.623033

Сгруппируем данные по первому столбцу и найдем сумму элементов в каждой группе

df.groupby('A').sum() print(df)

Обратите внимание, что в результате отсутствует столбец B, так как операция суммирования к нему неприменима

C D
A
bar -2.802588 2.42611
foo 3.146492 -0.63958

Группировать можно и иерархически, например указав два столбца

df.groupby(['A','B']).sum() print(df)

C D
A B
bar one -1.814470 2.395985
three -0.595447 0.166599
two -0.392670 -0.136473
foo one -1.195665 -0.616981
three 1.928123 -1.623033
two 2.414034 1.600434

Все значения из столбцов можно объединить с помощью другой функции

df.groupby(['A', 'B']).agg(lambda x: ','.join(x))

Или

df.groupby(['A', 'B']).apply(list))

После группировки столбцы A и B стали элементами составного индекса. Но это не помешает фильтровать строки по значениями этого индекса

df.index.get_level_values('A')

Временные последовательности

Временная последовательность отражает зависимость некоторого параметра от времени, например среднюю температуру в городе за историю наблюдений или курс акций по дням. pandas имеет простой и мощный интерфейс для работы с данными такого типа (например, если данные записаны с точностью до секунды их легко преобразовать в пятиминутные).

Создадим такую временную последовательность

rng = pd.date_range('1/1/2011', periods=72, freq='H') # Создадим временной диапазон: 72 часа начиная с 1 января 2011 ts = pd.Series(np.random.randn(len(rng)), index=rng) # Используем его в качестве индекса для случайной величины print(ts.head())

2011-01-01 00:00:00 0.469112
2011-01-01 01:00:00 -0.282863
2011-01-01 02:00:00 -1.509059
2011-01-01 03:00:00 -1.135632
2011-01-01 04:00:00 1.212112
Freq: H, dtype: float64

Посчитаем, например, среднее значение по дням

print(ts.resample('D').mean())

2011-01-01 -0.319569
2011-01-02 -0.337703
2011-01-03 0.117258
Freq: D, dtype: float64

Здесь мы встретились с операцией передискретизации или ресемплинга. Эта операция изменяет частоту с которой записаны значения параметра, в нашем примере мы уменьшили эту частоту в 24 раза: с 1 часа до 1 дня (resample()), в качестве нового значения выбрали среднее (mean()).

Диаграммы

pandas был бы не pandas если бы не давал возможности легко нарисовать таблицу на диаграмме. Для отображения картинки библиотека использует уже знакомый matplotlib.

Например

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)) # Создадим случайный набор данных с датами в качестве индекса ts = ts.cumsum() # Посчитаем кумулятивную сумму для всех значений ts.plot() # и отобразим ее на экране

Можно рисовать значения и из таблиц с множеством столбцов

df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,columns=['A', 'B', 'C', 'D']) df = df.cumsum() plt.figure() df.plot() plt.legend(loc='best')

Задача 6

Решить задачу 5 с помощью функции группировки

Задача 7

Найти наибольшую и наименьшую температуры - за всю историю наблюдений - за год - за месяц

Задача 8

Нарисовать среднее значение температуры по годам и месяцам

Задача 9

Найти год с самым жарким месяцем