Kezdjük a szokásos importokkal:
%pylab inline
import pandas as pd
Beolvasni már tudunk DataFrame-et, mi van, ha saját magunk akarjuk létrehozni?
Legkézenfekvőbb oszlopokból egy szótár segítségével létrehozni, melyben a különböző kulcsokhoz egy-egy lista, illetve tömb tartozik:
df=pd.DataFrame({'random1':random.random(4),
'nulla':[0 for i in range(4)]})
df
Indexet is megadhatunk kézzel.
df=pd.DataFrame({'random1':random.random(4),
'nulla':[0 for i in range(4)]},
index=['a','b','c','d'])
df
Ha sorokból akarjuk létrehozni, akkor a sorok listájából hozhatjuk létre. Az oszlopok neveit a columns argumentumban adhatjuk meg.
sor1=random.random(4)
sor2=[0 for i in range(4)]
df=pd.DataFrame([sor1,sor2],columns=['a','b','c','d'],
index=['random','nulla'])
df
2 dimenziós numpy tömbből is létrehozhatjuk.
df=pd.DataFrame(random.random((2,4)),columns=['a','b','c','d'],
index=['random','random2'])
df
df=pd.read_csv("data/kisnevsor.csv",index_col=0)
A pandas a DataFrame-ben tárolt értékeket elsősorban a fejléccel és a sorok neveivel teszi elérhetővé.
Már láttuk, ha egy oszlop nevét stringként szögletes zárójelekben írjuk a DataFrame neve mögé, visszakapjuk az oszlopot.
df["Eszter"]
Ha több oszlopot is vissza szeretnénk kapni, akkor azokat egy stringeket tartalmazó listában írjuk a DataFrame mögötti szögletes zárójelbe.
df[["Eszter","Nem","Kor"]]
Láttuk, hogy egy sort a loc konstrukcióval kérhetünk le név szerint.
df.loc['Bálint']
Több sort az oszlopokhoz hasonlóan kérhetünk le.
df.loc[['Bálint','Csenge']]
Aki szeretné ugyanúgy számokkal indexelni a DataFrame-et, mint egy array-t, annak erre az iloc
biztosít lehetőséget. Nézzük meg az előző eléréseket iloc
-kal!
df.iloc[:,0] # az első (0.) oszlop
df.iloc[0,0] # az első sor első eleme
A numpy tömböknél megismert minden indexelést tudunk itt használni.
df.iloc[::-1,3:5]
Sőt, a DataFrame belsejét átalakíthatjuk numpy array-jé, és alkalmazhatjuk rá a korábban tanult módszereket :-)
df.values
Név szerint lekérdezni az oszlopokat sokkal biztonságosabb, mint ha az oszlop sorszáma szerint kérdeznénk le (mint egy numpy tömbben) hiszen nem keverhetjük össze az indexeket!
Ha új sort szeretnénk hozzáadni a táblázathoz, akkor a .loc["Új_sor_indexe"]
változónak egy, az oszlopok számával megegyező hosszúságú listát kell odaadnunk.
df.loc["Dávid"]=[5,5,"fiú",20,'12:32']
df
Ha új oszlopot, akkor hasonlóan járunk el, de nem szükséges a loc
, mert az a sorokat indexeli.
df["Emelt"]=[0,0,1,1,0,0]
df
Ha sort szeretnénk törölni, a drop
függvénnyel tehetjük meg. Itt használhatjuk az inplace opciót, ami mindig arra vonatkozik, hogy a függvényünk egy új DataFrame-mel tér-e vissza, vagy felülírja a már meglévőt.
df.drop("Bálint",inplace=True)
df
Ha oszlopot szeretnénk törölni, akkor ugyanígy tehetjük meg, csak más tengely mentén kell törölni. Figyeljük meg, hogy itt az inplace nélkül egy DataFrame-et kapunk visszatérési értékként.
df.drop("Emelt",axis=1)
Írassuk ki a táblázatunk oszlopainak a nevét!
df.columns
Írassuk ki a táblázatunk sorainak a nevét!
df.index
Szükség lehet rá, hogy a fenti listákat tényleg Python-féle list-ként kapjuk vissza.
df.columns.tolist()
list(df.columns)
A teljes DataFrame-mel csinálhatunk műveteleket, ha azok értelmesek.
sub_df=df[["Eszter","Kor"]]
sub_df+1
Az oszlopokkal műveleteket végezhetünk, mint a numpy tömbökkel.
(df['Eszter']+2)/3
df['Eszter']/=2
df
df['Eszter']*df['Kor']
A stringekkel is!
df['Nem']+'ka'
A sorokkal is.
sub_df.loc["Dávid"]+3
A DataFrame-re is könnyű néhány beépített függvény segítségével különböző aggregált értékeket számolni.
Például álljon itt oszloponként a számok összege:
df.sum()
Mit tegyünk, ha ezt soronként szeretnénk visszakapni? Változtassuk meg az összegzés "tengelyét" (axis
)! Az előző eset ugyanis az alapértelmezett axis=0
volt, ami oszloponként végzi a műveletet. Csak a jegyeket tartalmazó oszlopokat összegezzük.
df[["Eszter","Orsi"]].sum(axis=1)
Számoltassuk meg, hány elem van az oszlopokban, illetve a sorokban!
df.count()
df.count(axis=1)
Ezt persze az array-hez hasonlóan is megtehettük volna:
df.shape
További ötletek beépített függvényekre: mean, median, min, max, std
.
Nagyon gyakran előfordul, hogy a táblázatunkból csak bizonyos feltételeknek megfelelő sorokat szeretnénk látni. Ha a táblázat sorainak számával megegyező hosszú igaz/hamis sorozatot adunk meg a DataFrame mögötti szögletes zárójelben, akkor csak az igaz elemeket fogjuk visszakapni visszatérési értékként.
Először nézzük meg, mi történik, ha megkérdezzük, hogy egy oszlop egyenlő-e egy értékkel:
df
df["Nem"]=="lány"
Láttuk, hogy minden sorhoz kaptunk egy igaz/hamis értéket. Most a fenti kifejezést beírjuk a []
-be:
df[df["Nem"]=="lány"]
De más feltételt is megadhatunk, például hogy kinek adott Eszter 2-esnél jobb jegyet.
df[df["Eszter"]>2]
Két feltételt összefűzhetünk egymáshoz, ilyenkor a &
és a |
operátorokat használjuk and és or helyett, mert azok nem tudnak két sorozatot elemenként összehasonlítani. A feltételeket zárójelbe kell tenni, különben hibát kapunk.
Ezek alapján az, akinek Eszter kettesnél jobbat adott, és idősebb 19 évesnél:
df[(df["Eszter"]>2) & (df["Kor"]>19)]
Szükségünk lehet arra, hogy a táblázatunkat sorba rendezzük valamelyik oszlop szerint. Ilyenkor a sort_values(by="oszlop_neve")
függvényt használjuk, melynek megadhatjuk, hogy növekvő (ascending=True
), vagy csökkenő (ascending=False
) sorrendben szeretnénk-e a rendezést.
A függvény visszatérési értéke a rendezett táblázat.
df.sort_values(by="Kor",ascending=False)
Sorba rendezhetünk több oszlop szerint is.
df.sort_values(by=["Orsi","Kor"],ascending=True)
Ha azt szeretnénk, hogy az eredeti DataFrame-ben rendezve tárolódjanak el a sorok, be kell kapcsolnunk az inplace=True
paramétert, ami felülírja a DataFrame-et a rendezés után.
df.sort_values(by="Kor",ascending=False,inplace=True)
Persze, ezt elérhettük volna szokásos értékadással is.
df=df.sort_values(by="Kor",ascending=False)
Ha a DataFrame indexe szerint szeretnénk sorba rendezni, akkor a sort_index()
függvény segít (itt is választhatjuk, hogy helyben szeretnénk-e a rendezést az inplace=True
segítségével):
df.sort_index(inplace=True)
df