2017-03-02 6 views
1

Ich habe folgende Pandas Datenrahmen:Wie zählen Untergruppen von kategorischen Daten in einem Pandas Dataframe?

import pandas as pd 
import numpy as np 
df = pd.DataFrame({"shops": ["shop1", "shop2", "shop3", "shop4", "shop5", "shop6"], "franchise" : ["franchise_A", "franchise_A", "franchise_A", "franchise_A", "franchise_B", "franchise_B"],"items" : ["dog", "cat", "dog", "dog", "bird", "fish"]}) 
df = df[["shops", "franchise", "items"]] 
print(df) 

    shops franchise items 
0 shop1 franchise_A dog 
1 shop2 franchise_A cat 
2 shop3 franchise_A dog 
3 shop4 franchise_A dog 
4 shop5 franchise_B bird 
5 shop6 franchise_B fish 

So ist jede Zeile eine einzigartige Probe shop1, shop2 usw., wobei jede Probe auf eine franchise_A Untergruppe gehört, franchise_B, franchise_C usw. In der Spalte items Es sind nur vier kategoriale Werte möglich: dog, cat, fish, bird. Meine Motivation ist es, ein Barplot der Nummer dog, cat, fish, bird für jedes "Franchise" zu erstellen.

ich die Ausgabe

franchise  dogs cats birds fish 
franchise_A  3  1  0  0 
franchise_B  0  0  1  1 

Ich glaube, sein Ich muss zuerst groupby() verwenden, zum Beispiel möchten

df.groupby("franchise").count() 
      shops items 
franchise     
franchise_A  4  4 
franchise_B  2  2 

Aber ich bin mir nicht sicher, wie ich die Anzahl der Artikel für jedes Franchise zählen.

Antwort

3

Sie value_counts mit unstack verwenden können, dank Nickil Maveli:

from collections import Counter 

print (df.groupby("franchise")['items'].value_counts().unstack(fill_value=0)) 
items  bird cat dog fish 
franchise       
franchise_A  0 1 3  0 
franchise_B  1 0 0  1 

andere Lösungen mit crosstab und pivot_table:

print (pd.crosstab(df["franchise"], df['items'])) 
items  bird cat dog fish 
franchise       
franchise_A  0 1 3  0 
franchise_B  1 0 0  1 

print (df.pivot_table(index="franchise", columns='items', aggfunc='size', fill_value=0)) 
items  bird cat dog fish 
franchise       
franchise_A  0 1 3  0 
franchise_B  1 0 0  1 
+2

'value_counts()' statt 'Counter' würde wirklich die ganze Sache befestigen. –

+1

@NickilMaveli - Danke. – jezrael

+0

Hier ist eine separate Frage: Sagen wir mal, es gab 5 Kategorien, eine davon war 'NaN'. Wie könnte ich NaN-Werte als separate Kategorie definieren? 'df.groupby (" franchise ") ['items']. value_counts(). entstack (fill_value = 0)' würde das nicht tun. – ShanZhengYang

2

Sie konnten die items Spalte in t enthalten er groupby, dann verwenden Sie size.

>>> df.groupby(['franchise', 'items']).size().unstack(fill_value=0) 

items  bird cat dog fish 
franchise       
franchise_A  0 1 3  0 
franchise_B  1 0 0  1 

(Raue) Benchmark

%timeit df.groupby(['franchise', 'items']).size().unstack(fill_value=0) 
100 loops, best of 3: 2.73 ms per loop 

%timeit (df.groupby("franchise")['items'].apply(Counter).unstack(fill_value=0).astype(int)) 
100 loops, best of 3: 4.18 ms per loop 

%timeit df.groupby('franchise')['items'].value_counts().unstack(fill_value=0) 
100 loops, best of 3: 2.71 ms per loop
Verwandte Themen