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 in n 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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow