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?
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
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)