Python: obtenez un décompte de fréquence basé sur deux colonnes (variables) dans pandas dataframe certains appers de ligne

93

Bonjour, j'ai le dataframe suivant.

    Group           Size

    Short          Small
    Short          Small
    Moderate       Medium
    Moderate       Small
    Tall           Large

Je veux compter la fréquence d'apparition de la même ligne dans le dataframe.

    Group           Size      Time

    Short          Small        2
    Moderate       Medium       1 
    Moderate       Small        1
    Tall           Large        1
emax
la source
1
Note sur les performances, y compris les alternatives: Pandas groupby.size vs series.value_counts vs collections.Counter with multiple series
jpp

Réponses:

145

Vous pouvez utiliser groupby's size:

In [11]: df.groupby(["Group", "Size"]).size()
Out[11]:
Group     Size
Moderate  Medium    1
          Small     1
Short     Small     2
Tall      Large     1
dtype: int64

In [12]: df.groupby(["Group", "Size"]).size().reset_index(name="Time")
Out[12]:
      Group    Size  Time
0  Moderate  Medium     1
1  Moderate   Small     1
2     Short   Small     2
3      Tall   Large     1
Andy Hayden
la source
7
Merci. Un ajout mineur pour sélectionner les k (= 20) valeurs supérieures en fonction de la fréquence ("Time"): df.groupby (["Group", "Size"]). Size (). Reset_index (name = "Time") .sort_values ​​(by = 'Time', croissant = False) .head (20);
Dileep Kumar Patchigolla
1
Notez simplement que l'utilisation .size()retournera Series pendant que .size().reset_index(name="Time")est un DataFrame. Merci Andy.
alemol
ou vous pouvez aussi faire df.groupby(by=["Group", "Size"], as_index=False).size()simplement
Naveen Kumar
51

La mise à jour après Pandas 1.1value_countsaccepte désormais plusieurs colonnes

df.value_counts(["Group", "Size"])

Vous pouvez également essayer pd.crosstab()

Group           Size

Short          Small
Short          Small
Moderate       Medium
Moderate       Small
Tall           Large

pd.crosstab(df.Group,df.Size)


Size      Large  Medium  Small
Group                         
Moderate      0       1      1
Short         0       0      2
Tall          1       0      0

EDIT: Afin de vous faire sortir

pd.crosstab(df.Group,df.Size).replace(0,np.nan).\
     stack().reset_index().rename(columns={0:'Time'})
Out[591]: 
      Group    Size  Time
0  Moderate  Medium   1.0
1  Moderate   Small   1.0
2     Short   Small   2.0
3      Tall   Large   1.0
BEN_YO
la source
7
agréable. vous pouvez même ajouter margins=Truepour obtenir les comptes marginaux!
Matt Hancock
0

L'autre posibbilité utilise .pivot_table()etaggfunc='size'

df_solution = df.pivot_table(index=['Group','Size'], aggfunc='size')
asantz96
la source