Autor notebooka: Jakub Nowacki.
Pandas to biblioteka dostarczająca wygodne w użyciu struktury danych i narzędzia do ich analizy. Inspirowane tutorialem 10 minutes to Pandas. Zobacz też dokumentację oraz Pandas Cheat Sheet
Pandas importujemy używając nazwy pandas
, najlepiej w całości jako pakiet. Często stosowany jest alias pd
.
In [2]:
import pandas as pd
import numpy as np # Nie wymagane, użyjemy tylko elementów
Podstawowymi strukturami danych w Pandas jest Series (seria) i DataFrame (obiekt tabeli); zobacz dokumentacje po więcej informacji.
In [3]:
l = [1,3,5,np.nan,6,8]
s = pd.Series(l)
s
Out[3]:
Series posiada indeks, który będzie stworzony automatycznie jeżeli nie został przekazany lub można go stworzyć:
In [4]:
daty = pd.date_range('20170101', periods=6)
daty
Out[4]:
In [5]:
s = pd.Series(l, index=daty)
s
Out[5]:
Niemniej, może to być każda seria która jest przynajmniej tak długa jak dane:
In [6]:
s = pd.Series(np.random.randn(5), index=list('abcde'))
s
Out[6]:
Pobierać dane z Series możemy jak w Numpy:
In [7]:
print('s[1] = \n{}'.format(s[1]))
print('s[2:] = \n{}'.format(s[2:]))
print('s[1:-2] = \n{}'.format(s[1:-2]))
Możemy też robić to jak w słowniku (lub lepiej), jeżeli indeks na to pozwala:
In [8]:
print('s["b"] = \n{}'.format(s["b"]))
print('s["c":] = \n{}'.format(s["c":]))
print('s["b":"c"] = \n{}'.format(s["b":"c"]))
Można też wykonywać operacje na serii:
In [9]:
print('s*5 = \n{}'.format(s*5))
print('s**3 = \n{}'.format(s**3))
print('s*s = \n{}'.format(s*s))
print('s+s = \n{}'.format(s+s))
In [10]:
df = pd.DataFrame(np.random.randn(6,4), index=daty, columns=list('ABCD'))
df
Out[10]:
Można też przekazać słownik:
In [15]:
df2 = pd.DataFrame({ 'A' : 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' })
df2.E
Out[15]:
Albo kolekcji słowników:
In [14]:
df3 = pd.DataFrame([{'A': 1, 'B': 2}, {'C': 3}])
df3.A
Out[14]:
Istnieje też wiele innych metod tworzenia i czytania DataFrame, które zostały opicane w dokumentacji.
Pobierać dane można jak w serii i innych kolekcjach Pythonowych:
In [16]:
print("df['A'] = \n{}".format(df['A'])) # Kolumna
print("df[1:3] = \n{}".format(df[1:3]))
Niemniej zalecane jest używanie zoptymalizowanych funkcji Pandas:
In [19]:
df3[['A', 'B']]
Out[19]:
In [18]:
print("df.loc[:,'A']) = \n{}".format(df.loc[:,'A']))
print("df.loc[daty[0],'A'] = \n{}".format(df.loc[daty[0],'A']))
print("df.at[daty[0],'A'] = \n{}".format(df.at[daty[0],'A'])) # Pobiera skalar szybciej
print("df.iloc[:,0]] = \n{}".format(df.iloc[:,0]))
print("df.iloc[0,0] = \n{}".format(df.iloc[0,0]))
print("df.iat[0,0] = \n{}".format(df.iat[0,0])) # Pobiera skalar szybciej
print("df.ix[0,0] = \n{}".format(df.iat[0,0]))
Można też używać wyrażeń boolowskich do filtrowania wyników:
In [20]:
df[df.B > 0.5]
Out[20]:
Jest też dostęp do poszczególnych elementów takich jak:
In [21]:
print('Indeks:\n{}'.format(df.index))
print('Kolumny:\n{}'.format(df.columns))
print('Początek:\n{}'.format(df.head(2)))
print('Koniec:\n{}'.format(df.tail(3)))
Dane można też sortować po indeksie:
In [22]:
df.sort_index(ascending=False)
Out[22]:
Po kolumnach:
In [23]:
df.sort_index(axis=1, ascending=False)
Out[23]:
Lub po wartościach:
In [26]:
df.sort_values(['B', 'C'])
Out[26]:
Można też tabelę transponować:
In [27]:
df.T
Out[27]:
Nową kolumnę dodajemy przez przypisanie:
In [28]:
df3['Z'] = ['aa', 'bb']
df3
Out[28]:
Zmiana pojedynczej wartości może być również zrobiona przez przypisanie; używamy wtedy komend lokalizacyjnych, np:
In [30]:
df3.at[0, 'C'] = 33
df3
Out[30]:
In [ ]:
df3.at[2,:] = np.nan
df3
Pandas posiada również metody radzenia sobie z brakującymi danymi:
In [ ]:
df3.dropna(how='any')
In [ ]:
df3.dropna(how='all')
In [ ]:
df3.fillna(-100)
Dostępne są również funkcje statystyczne, np:
In [31]:
df.describe()
Out[31]:
In [ ]:
df.mean()
Dodatkowo, można używać funkcji znanych z baz danych jak grupowanie czy złączenie (join):
In [ ]:
df2.groupby('E').size()
In [ ]:
df2.groupby('E').mean()
In [ ]:
df2.join(df3, how='left', rsuffix='_3')
In [ ]:
df2.merge(df3)
In [ ]:
df2.merge(df3, how='outer')
In [ ]:
# Odpowiednik:
# df2.join(df3, how='left', rsuffix='_3')
df2.merge(df3, right_index=True, left_index=True, how='left', suffixes=('', '_3'))
In [ ]:
df2.append(df3)
In [ ]:
df2.append(df3, ignore_index=True)
In [ ]:
pd.concat([df2, df3])
In [ ]:
pd.concat([df2, df3], ignore_index=True)
In [32]:
pd.concat([df2, df3], join='inner')
Out[32]:
Należy stworzyć DataFrame samochody
z losową kolumną liczb całkowitych przebieg
z przedziału [0, 200 000] oraz spalanie
z przedziału [2, 20].
marka
pochodzenie
:nowy
uzywany
z niemiec
marce
i po pochodzenie
:
In [44]:
n = 50
# np.random.randn # rozklad normalny
samochody = pd.DataFrame({
'przebieg': np.random.randint(0, 200_000, n),
'spalanie': 2 + 18*np.random.rand(n),
})
samochody.head()
#samochody.describe()
Out[44]:
In [48]:
samochody.loc[samochody.spalanie < 5, 'marka'] = 'WV'
In [54]:
samochody['marka'] = pd.cut(samochody.spalanie,
bins=[0, 5, 10, 100],
labels=['VW', 'Ford', 'UAZ'])
samochody.head()
Out[54]:
In [63]:
samochody['pochodzenie'] = pd.cut(samochody.przebieg,
bins=[0, 100, 100_000, np.inf],
labels=['nowy', 'uzywany', 'z niemiec'])
samochody.groupby(['marka', 'pochodzenie']).describe().T
Out[63]:
In [ ]: