Шестаков А.В. Майнор по анализу данных - 19/01/2016
Модуль Pandas существенно упрощает работу с табличными данными в Python. Работа в нем во многом напоминает работу с таблицами в SQL с тем отличием, что в Pandas тебе не хочется рвать волосы на голове это делать гораздо проще, и в нем заложены некоторые дополнительные инструменты по работе с данными.
Как уже было оговорено на предыдущем семинаре, помимо стандартной библиотеки matplotlib, для "рисования" в Python можно использовать достойную альтернативу, чем сейчас и займемся.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.style.use('ggplot')
%matplotlib inline
Основными структурами являются Series и DataFrame.
Series – это проиндексированный одномерный массив значений. Он похож на простой словарь типа dict, где имя элемента будет соответствовать индексу, а значение – значению записи.
ser = pd.Series(np.random.rand(5), index=['a', 'b', 'c', 'd', 'e'])
В Pandas предусмотрены разные способы индексирования
ser.index
ser['a']
ser[['a', 'b']]
ser.loc['a']
ser[0]
# ser.iloc['a']
ser.iloc[0]
idx = ser>0.5
ser[idx]
# Автоматическое выравнивание по индексу
print ser + ser[1:]
DataFrame — это проиндексированный многомерный массив значений, соответственно каждый столбец DataFrame, является структурой Series. Индексирование в DataFrame ровно тоже, что и в Series, с тем отличием, что добавляется второе измерение.
df = pd.DataFrame(np.random.randn(10, 3),
index=range(10),
columns=['A', 'B', 'C'])
print df.index
print df.columns
df[['A', 'B']]
df.loc[1:3, ['A', 'B']]
df.iloc[1:3, 0:2]
df.ix[1:3, ['A', 'B']]
idx = df>0
idx
Есть некоторые нюансы с форматом индексов, а так же нюансы, возникающие при присваивании значений в DataFrame. С ними вы встретитесь на практике. В общем RTFM!
Достаточно полезная команда, позволяющая "мельком" взглянуть на вашу таблицу с данными
df.head()
Краткая описательная статистика
df.describe()
Перевод данных в нужный тип
df.dtypes
df.A = df.A.astype(int)
df.head()
df.dtypes
Важно контролировать какой тип данных содержится в колонке. Иногда это можно сэкономить уйму времени при отлове багов в работе программы.
В DataFrame можно хранить данные разной природы
df.loc[0, 'A'] = 'lalaley'
df.head()
df.dtypes
df.iloc[0:4, 0].values
Удаление\добавление строк
df.drop(0)
df.loc[0] = [1,2,3]
df
В 1968 году была опубликована статья под интригующем названием Correlation of Performance Test Scores with Tissue Concentration of Lysergic Acid Diethylamide in Human Subjects.
К статье приложен небольшой набор данных, состоящий из 7 наблюдений
data_types = {'Drugs': float,
'Score': float}
df = pd.read_csv('drugs-and-math.csv', index_col=0, sep=',', dtype=data_types)
print df.shape
print df.columns
print df.index
df
Таблица уже отсортирована по колонке Drugs, сделаем сортировку по Score
df.sort_values('Score',
ascending=False,
inplace=True)
df.describe().T # Иногда так лучше
df.plot(kind='box')
df.plot(x='Drugs', y='Score', kind='bar')
# df.plot(x='Drugs', y='Score')
df.plot(x='Drugs', y='Score', kind='scatter')
Мы явно видим тенденцию..
df.corr(method='pearson')
Ну и напоследок графичек от seaborn!
import seaborn as sns
# sns.regplot(x='Drugs', y='Score', data=df)
sns.jointplot(x='Drugs', y='Score',
data=df, kind='reg')
df = pd.read_csv('2008.csv', parse_dates=4)
print df.shape
print df.columns
df.head().T
df.describe().T
# Посмотрим, сколько уникальных рейсов у нас представлено
df['FlightNum'].nunique()
Мы можем выполнять какую-нибудь группировку, что того, чтобы расчитывать различные аггрегированные статистики.
# Например, найдите топ-3 рейсов, совершивших самые длинные перелеты за 2008 год?
df.groupby('FlightNum')['Distance']\
.sum().sort_values(ascending=False)\
.iloc[0:3]
# Можно так:
df.groupby('FlightNum')\
.agg({'Distance': [np.mean, np.sum, 'count'],
'Cancelled': {'_total': np.sum}})\
.sort_values(('Distance', 'sum'), ascending=False)\
.iloc[0:3]
Еще полезная функция - построение сводной таблицы
pd.crosstab(df.Month, df.DayOfWeek)
# Иногда на такого рода таблицы проще смотреть так
plt.imshow(pd.crosstab(df.Month, df.DayOfWeek),
cmap='seismic',interpolation='none')
Гистограммы!
df.hist('Distance', bins=20)
Смотрим на даты!
df['Date'] = pd.to_datetime(df.Year*10000 + df.Month*100 + df.DayofMonth,
format='%Y%m%d')
res = df.groupby('Date')['FlightNum'].agg('count')
Ничего не заметили?
res.plot()
pd.rolling_mean(res, 7).plot()