Учебный ноутбук по теме "Пакет Pandas"
автор: Александр Дьяконов (alexanderdyakonov.wordpress.com)
# подгружаем все нужные пакеты
import pandas as pd
import numpy as np
# для встроенных картинок
%pylab inline
# чуть покрасивше картинки:
pd.set_option('display.mpl_style', 'default')
figsize(10, 3)
# загрузка данных
# Excel
data2 = pd.read_excel('D:\\filename.xlsx', sheetname='1')
# csv-файл
data = pd.read_csv('D:\\filename.csv', sep=';', decimal=',')
data.to_csv('foo.csv') # сохранение
# HDF5
pd.read_hdf('foo.h5', 'df')
df.to_hdf('foo.h5', 'df') # сохранение
# создание дата-фрейма
data = pd.DataFrame({ 'A' : [1., 4., 2., 1.],
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' }, index=pd.period_range('Jan-2000', periods=4, freq='M'))
print data
# второй способ
tmp = dict([('A',[1., np.nan, 2., 1.]), ('B',[2.2, np.nan, np.nan, 0.0])]) # ещё один способ
data2 = pd.DataFrame(tmp)
print data2
# простейшие операции
# столбцы
print data.columns
# строки - но тут временная индексация
print data.index
# сами данные
print data
# сортировка
print data.sort(columns='A')
# типы
print data.dtypes
# статистика + транспонирование
print data.describe().T
# индексация
data.at['2000-01','A'] = 10.
print data.loc['2000-01':'2000-02',['D','B','A']]
data.iat[0,1] = pd.Timestamp('19990101') # просто = '1999/01/01' не работает
print data.iloc[0:2,1:3]
# выбор с проверкой на вхождение
print data[data['E'].isin(['test','valid'])]
# если не делать принт - выглядит круче
data.tail(3).T
# операции с НаНами
# маска Нанов
print data2.isnull()
# nan автоматически не учитываются
print data2.mean()
# тоже обходятся nan:
print data2.apply(np.cumsum)
# удаление Нанов
data3 = data2.dropna()
print data3
# заполнение Нанов
print data2.fillna(value=5.5)
# заполнение соседними значениями
print data2.ffill()
# не забывать data2 = data2.fillna(value=5.5)
data2
# как часто встречаются пары значений
d = pd.DataFrame({'A': [1,2,2,1,2,3,2,1,3], 'B': [1,2,3,4,1,2,3,3,4]})
pd.crosstab(d['A'], d['B'])
# все строки, в которых столбец начинается с определённой буквы
d = pd.DataFrame({'A': [1,2,2,1,2,3,2,1,3], 'B': ['as','bs','e','qq','aaa','a','e','qwr','www']})
d[d['B'].map(lambda x: x.startswith('a'))]
# замена определённых значений
d = pd.DataFrame({'A': [1,2,2,1,2,3,2,1,3], 'B': [1,2,3,4,1,2,3,3,4]})
d['B'][d['A']==1] = 0
# второй способ: d.ix[d['A']==1, 'B'] = 0
d
# использование масок
d = pd.DataFrame({'A': [1,2,2,1,2,3,2,1,3], 'B': [1,2,3,4,1,2,3,3,4]})
mask = d>1
print mask.T
d = d.where(mask,2)
d['C'] = np.where(d['B']>3, 'high', 'low')
d.T
# объединение дата-фреймов
left = pd.DataFrame({'key': [1,2,1], 'l': [1, 2, 3]})
right = pd.DataFrame({'key': [1,2,3], 'r': [4, 5, 6]})
print left
print right
pd.merge(left, right, on='key')
# добавление к дата-фрейму
tmp = dict([('A',[1., 3., 2., 1.]), ('B',[2.2, 1.1, 3.3, 0.0]), ('C', 1)]) # ещё один способ
df = pd.DataFrame(tmp)
# добавление к дата-фрейму
df = df.append(df.iloc[1:3])
df
# информация
data.info() # по памяти
#??? data.memory_usage() # аналогично
# временные ряды
# создание
rng = pd.date_range('1/1/2012', periods=9, freq='D')
# дни
print rng.day
# дни недели
print rng.weekday
rng = pd.date_range('1/1/2012', periods=200, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
# ресэмплирование
ts = ts.resample('Min', how='sum')
print ts
# ???
ts.tz_localize('UTC')
print ts
# решение задачи
# для каждого унакального значения A найти минимальный B
import pandas as pd
d = pd.DataFrame({'A': [1,2,2,1,3,3], 'B': [1,2,3,3,2,1]})
print d
# первый способ
print d.loc[d.groupby('A')['B'].idxmin()]
# второй способ
print d.sort('B').groupby('A', as_index=False).first()
# операции по группам (индуцируются разбиением по определённому признаку)
d = pd.DataFrame({'A': [1,2,2,1,1,2,2], 'B': [1,2,np.nan,5,3,1,10]})
d = d.sort('A')
print d
d['shift_B'] = d.groupby('A')['B'].shift(1) # сдвиг групп
d['counts'] = d.groupby(['A'])['B'].transform(len) # число элементов в группе
d
d = pd.DataFrame({'A': [1,2,2,1,1,2,2], 'B': [1,0,np.nan,1,0,1,0]})
d = d.sort('A')
print d
# длина и сколько 1 в каждой группе
d.groupby('A').agg({'A': len, 'B': lambda x: sum(x == 1)})
# Строковые операции
s = pd.Series(['AbA', 'Sasha', 'DataMining']) # ( [] )
s.str.lower()
# иерархическая (многоуровневая) индексация
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two',
'one', 'two', 'one', 'two']]))
print tuples
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
print index
index
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
print df
print df.stack() # обратная операция unstack()
# панель (3D-дата-фрейм)
d = pd.DataFrame({'A': [1,2,2], 'B': [1,2,3]})
d2, d3 = d.copy(), d.copy()
p = pd.Panel({'df1':d, 'df2':d2, 'df3':d3})
p = p.transpose(2,0,1)
print p['A']
p
# графика
d = pd.DataFrame({"IQ": [1,4,3,2]})
d.index = ['man', 'woman', 'dog', 'cat']
d.plot(kind='barh')
# создание категориального признака = интервалы попаданий
x = np.random.randn(10000)
y = pd.cut(x,10)
z = pd.value_counts(y)
z.plot(figsize=(20,3))
pd.DataFrame(x).plot(kind='kde')
pd.DataFrame(z).T
#???
# категорный тип (new)
tmp = dict([('A',[1, 1, 2, 2]), ('B',[1., 2., 1., 2.])]) # ещё один способ
df = pd.DataFrame(tmp)
df['A'] = df['A'].astype('category') # преобразование в категорный тип
print df['A'].cat.categories
df