web-dev-qa-db-fra.com

Comment obtenir le nombre de valeurs pour plusieurs colonnes à la fois dans Pandas DataFrame?

Etant donné un Pandas DataFrame qui a plusieurs colonnes avec des valeurs catégorielles (0 ou 1), est-il possible d’obtenir facilement les value_counts pour chaque colonne en même temps?

Par exemple, supposons que je génère un DataFrame comme suit:

import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd'))

Je peux obtenir un DataFrame comme ceci:

   a  b  c  d
0  0  1  1  0
1  1  1  1  1
2  1  1  1  0
3  0  1  0  0
4  0  0  0  1
5  0  1  1  0
6  0  1  1  1
7  1  0  1  0
8  1  0  1  1
9  0  1  1  0

Comment puis-je obtenir facilement le nombre de valeurs pour chaque colonne et obtenir ce qui suit?

   a  b  c  d
0  6  3  2  6
1  4  7  8  4

Ma solution actuelle est:

pieces = []
for col in df.columns:
    tmp_series = df[col].value_counts()
    tmp_series.name = col
    pieces.append(tmp_series)
df_value_counts = pd.concat(pieces, axis=1)

Mais il doit y avoir un moyen plus simple, comme empiler, pivoter ou groupby?

37
Xin

Il suffit d’appeler apply et de passer pd.Series.value_counts :

In [212]:
df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd'))
df.apply(pd.Series.value_counts)
Out[212]:
   a  b  c  d
0  4  6  4  3
1  6  4  6  7
65
EdChum

Il existe en fait une manière assez intéressante et avancée de résoudre ce problème avec crosstab et melt

df = pd.DataFrame({'a': ['table', 'chair', 'chair', 'lamp', 'bed'],
                   'b': ['lamp', 'candle', 'chair', 'lamp', 'bed'],
                   'c': ['mirror', 'mirror', 'mirror', 'mirror', 'mirror']})

df

       a       b       c
0  table    lamp  mirror
1  chair  candle  mirror
2  chair   chair  mirror
3   lamp    lamp  mirror
4    bed     bed  mirror

On peut d'abord fondre le DataFrame

df1 = df.melt()
df1

   columns   index
0        a   table
1        a   chair
2        a   chair
3        a    lamp
4        a     bed
5        b    lamp
6        b  candle
7        b   chair
8        b    lamp
9        b     bed
10       c  mirror
11       c  mirror
12       c  mirror
13       c  mirror
14       c  mirror

Et utilisez ensuite la fonction Analyse croisée pour compter les valeurs de chaque colonne. Cela conserve le type de données en tant qu'intts, ce qui ne serait pas le cas pour la réponse actuellement sélectionnée:

pd.crosstab(index=df['index'], columns=df['columns'])

columns  a  b  c
index           
bed      1  1  0
candle   0  1  0
chair    2  1  0
lamp     1  2  0
mirror   0  0  5
table    1  0  0

Ou sur une ligne, qui étend les noms de colonne en noms de paramètres avec ** (c'est avancé)

pd.crosstab(**df.melt(var_name='columns', value_name='index'))

Également, value_counts est maintenant une fonction de niveau supérieur. Vous pouvez donc simplifier la réponse actuellement sélectionnée:

df.apply(pd.value_counts)
18
Ted Petrou