====== Операции с датафреймами/сериями ======
===== Математические функции и статистика =====
В панде уже реализовано множество математических функций для работы с данными, уже сохраненными в соответствующей структуре данных. Весь их список стоит посмотреть по ссылкам на общей странице (раздел "Внешняя документация")
Рассмотрим некоторые из них.
Функция 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() # и отобразим ее на экране
{{:python:series_plot_basic.png?400|}}
Можно рисовать значения и из таблиц с множеством столбцов
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 ======
Найти год с самым жарким месяцем