pandas
Gegevens groeperen
Zoeken…
Basis groepering
Groeperen op één kolom
Het volgende DataFrame gebruiken
df = pd.DataFrame({'A': ['a', 'b', 'c', 'a', 'b', 'b'],
'B': [2, 8, 1, 4, 3, 8],
'C': [102, 98, 107, 104, 115, 87]})
df
# Output:
# A B C
# 0 a 2 102
# 1 b 8 98
# 2 c 1 107
# 3 a 4 104
# 4 b 3 115
# 5 b 8 87
Groepeer op kolom A en krijg de gemiddelde waarde van andere kolommen:
df.groupby('A').mean()
# Output:
# B C
# A
# a 3.000000 103
# b 6.333333 100
# c 1.000000 107
Groeperen op meerdere kolommen
df.groupby(['A','B']).mean()
# Output:
# C
# A B
# a 2 102.0
# 4 104.0
# b 3 115.0
# 8 92.5
# c 1 107.0
Merk op hoe na het groeperen van elke rij in het resulterende DataFrame wordt geïndexeerd door een tuple of MultiIndex (in dit geval een paar elementen uit kolommen A en B).
Gebruik de functie agg
om verschillende aggregatiemethoden in één keer toe te passen, bijvoorbeeld om het aantal items in elke groep te tellen en hun gemiddelde te berekenen:
df.groupby(['A','B']).agg(['count', 'mean'])
# Output:
# C
# count mean
# A B
# a 2 1 102.0
# 4 1 104.0
# b 3 1 115.0
# 8 2 92.5
# c 1 1 107.0
Nummers groeperen
Voor het volgende DataFrame:
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'Age': np.random.randint(20, 70, 100),
'Sex': np.random.choice(['Male', 'Female'], 100),
'number_of_foo': np.random.randint(1, 20, 100)})
df.head()
# Output:
# Age Sex number_of_foo
# 0 64 Female 14
# 1 67 Female 14
# 2 20 Female 12
# 3 23 Male 17
# 4 23 Female 15
Age
in drie categorieën (of bakken). Bakken kunnen worden gegeven als
- een geheel getal
n
dat het aantal bins aangeeft - in dit geval worden de gegevens van het dataframe verdeeld inn
intervallen van gelijke grootte - een reeks gehele getallen die het eindpunt aangeven van de opengelaten intervallen waarin de gegevens zijn verdeeld - bijvoorbeeld
bins=[19, 40, 65, np.inf]
creëert drie leeftijdsgroepen(19, 40]
,(40, 65]
en(65, np.inf]
.
Panda's wijst automatisch de stringversies van de intervallen toe als label. Het is ook mogelijk om eigen labels definiëren door het definiëren van een labels
parameter als een lijst van strings.
pd.cut(df['Age'], bins=4)
# this creates four age groups: (19.951, 32.25] < (32.25, 44.5] < (44.5, 56.75] < (56.75, 69]
Name: Age, dtype: category
Categories (4, object): [(19.951, 32.25] < (32.25, 44.5] < (44.5, 56.75] < (56.75, 69]]
pd.cut(df['Age'], bins=[19, 40, 65, np.inf])
# this creates three age groups: (19, 40], (40, 65] and (65, infinity)
Name: Age, dtype: category
Categories (3, object): [(19, 40] < (40, 65] < (65, inf]]
Gebruik het in groupby
om het gemiddelde aantal foo te krijgen:
age_groups = pd.cut(df['Age'], bins=[19, 40, 65, np.inf])
df.groupby(age_groups)['number_of_foo'].mean()
# Output:
# Age
# (19, 40] 9.880000
# (40, 65] 9.452381
# (65, inf] 9.250000
# Name: number_of_foo, dtype: float64
Leeftijdsgroepen en geslacht doorkruisen:
pd.crosstab(age_groups, df['Sex'])
# Output:
# Sex Female Male
# Age
# (19, 40] 22 28
# (40, 65] 18 24
# (65, inf] 3 5
Kolomselectie van een groep
Wanneer u een groep uitvoert, kunt u een enkele kolom of een lijst met kolommen selecteren:
In [11]: df = pd.DataFrame([[1, 1, 2], [1, 2, 3], [2, 3, 4]], columns=["A", "B", "C"]) In [12]: df Out[12]: A B C 0 1 1 2 1 1 2 3 2 2 3 4 In [13]: g = df.groupby("A") In [14]: g["B"].mean() # just column B Out[14]: A 1 1.5 2 3.0 Name: B, dtype: float64 In [15]: g[["B", "C"]].mean() # columns B and C Out[15]: B C A 1 1.5 2.5 2 3.0 4.0
U kunt ook agg
gebruiken om kolommen en aggregatie op te geven voor het uitvoeren van:
In [16]: g.agg({'B': 'mean', 'C': 'count'}) Out[16]: C B A 1 2 1.5 2 1 3.0
Aggregeren op grootte versus op telling
Het verschil tussen size
en count
is:
size
telt NaN
waarden, count
niet.
df = pd.DataFrame(
{"Name":["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"],
"City":["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"],
"Val": [4, 3, 3, np.nan, np.nan, 4]})
df
# Output:
# City Name Val
# 0 Seattle Alice 4.0
# 1 Seattle Bob 3.0
# 2 Portland Mallory 3.0
# 3 Seattle Mallory NaN
# 4 Seattle Bob NaN
# 5 Portland Mallory 4.0
df.groupby(["Name", "City"])['Val'].size().reset_index(name='Size')
# Output:
# Name City Size
# 0 Alice Seattle 1
# 1 Bob Seattle 2
# 2 Mallory Portland 2
# 3 Mallory Seattle 1
df.groupby(["Name", "City"])['Val'].count().reset_index(name='Count')
# Output:
# Name City Count
# 0 Alice Seattle 1
# 1 Bob Seattle 1
# 2 Mallory Portland 2
# 3 Mallory Seattle 0
Groepen samenvoegen
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: df = pd.DataFrame({'A': list('XYZXYZXYZX'), 'B': [1, 2, 1, 3, 1, 2, 3, 3, 1, 2],
'C': [12, 14, 11, 12, 13, 14, 16, 12, 10, 19]})
In [4]: df.groupby('A')['B'].agg({'mean': np.mean, 'standard deviation': np.std})
Out[4]:
standard deviation mean
A
X 0.957427 2.250000
Y 1.000000 2.000000
Z 0.577350 1.333333
Voor meerdere kolommen:
In [5]: df.groupby('A').agg({'B': [np.mean, np.std], 'C': [np.sum, 'count']})
Out[5]:
C B
sum count mean std
A
X 59 4 2.250000 0.957427
Y 39 3 2.000000 1.000000
Z 35 3 1.333333 0.577350
Exporteer groepen in verschillende bestanden
U kunt het object herhalen dat wordt geretourneerd door groupby()
. De iterator bevat (Category, DataFrame)
tupels.
# Same example data as in the previous example.
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'Age': np.random.randint(20, 70, 100),
'Sex': np.random.choice(['Male', factor'Female'], 100),
'number_of_foo': np.random.randint(1, 20, 100)})
# Export to Male.csv and Female.csv files.
for sex, data in df.groupby('Sex'):
data.to_csv("{}.csv".format(sex))
transformeren gebruiken om statistieken op groepsniveau te krijgen met behoud van het oorspronkelijke dataframe
voorbeeld:
df = pd.DataFrame({'group1' : ['A', 'A', 'A', 'A',
'B', 'B', 'B', 'B'],
'group2' : ['C', 'C', 'C', 'D',
'E', 'E', 'F', 'F'],
'B' : ['one', np.NaN, np.NaN, np.NaN,
np.NaN, 'two', np.NaN, np.NaN],
'C' : [np.NaN, 1, np.NaN, np.NaN,
np.NaN, np.NaN, np.NaN, 4]})
df
Out[34]:
B C group1 group2
0 one NaN A C
1 NaN 1.0 A C
2 NaN NaN A C
3 NaN NaN A D
4 NaN NaN B E
5 two NaN B E
6 NaN NaN B F
7 NaN 4.0 B F
Ik wil het aantal niet-ontbrekende waarnemingen van B krijgen voor elke combinatie van group1
en group2
. groupby.transform
is een zeer krachtige functie die precies dat doet.
df['count_B']=df.groupby(['group1','group2']).B.transform('count')
df
Out[36]:
B C group1 group2 count_B
0 one NaN A C 1
1 NaN 1.0 A C 1
2 NaN NaN A C 1
3 NaN NaN A D 0
4 NaN NaN B E 1
5 two NaN B E 1
6 NaN NaN B F 0
7 NaN 4.0 B F 0