2017-03-07 9 views
2

Vielen Dank für Ihre Hilfe.Python Pandas groupby mehrere Spalten

Ich habe Daten, die wie folgt aussieht:

city, room_type 
A, X 
A, Y 
A, Z 
B, X 
B, Y 
B, Y 

ich mein Ergebnis so aussehen wollen:

city, count(X), count(Y), count(z) 
A, 1, 1, 1 
B, 1, 2, 0 

ich nach Stadt bin Gruppierung und ich möchte die Anzahl der zeigen, jeder room_type in jeder Stadt.

Jeder Weg, dies mit Python Pandas zu tun? Vielen Dank.

Ich lernte SQL vor Jahren und denke, dass es möglich gewesen sein könnte. Ich bin sicher, Python kann das Gleiche tun. Vielen Dank!

Antwort

4

Sie können crosstab mit rename Spalten verwenden:

df = pd.crosstab(df.city, df.room_type).rename(columns=lambda x: 'count({})'.format(x)) 
print (df) 
room_type count(X) count(Y) count(Z) 
city         
A     1   1   1 
B     1   2   0 

Einer anderen Lösung mit groupby und size oder value_counts, für reshape unstack verwendet wird:

df = df.groupby(['city', 'room_type']).size().unstack(fill_value=0) 
     .rename(columns=lambda x: 'count({})'.format(x)) 
print (df) 
room_type count(X) count(Y) count(Z) 
city         
A     1   1   1 
B     1   2   0 

df = df.groupby('city')['room_type'].value_counts().unstack(fill_value=0) 
     .rename(columns=lambda x: 'count({})'.format(x)) 
print (df) 
room_type count(X) count(Y) count(Z) 
city         
A     1   1   1 
B     1   2   0 
+0

Vielen Dank! –

+0

Wenn meine oder eine andere Antwort hilfreich war, vergiss [accept] (http://meta.stackexchange.com/a/5235/295067) nicht. Vielen Dank. – jezrael

2

Eine Lösung jezrael gab nicht; -)

s = pd.value_counts([tuple(i) for i in df.values.tolist()]) 
s.index = pd.MultiIndex.from_tuples(s.index.values, names=['city', None]) 
s.unstack(fill_value=0).rename(columns='count({})'.format).reset_index() 

    city count(X) count(Y) count(Z) 
0 A   1   1   1 
1 B   1   2   0 

Beteiligtere

cities = pd.unique(df.city) 
room_types = pd.unique(df.room_type) 
d1 = pd.DataFrame(
    np.zeros((len(cities), len(room_types)), dtype=int), 
    cities, 
    room_types 
) 
for r, c in df.values: 
    d1.set_value(r, c, d1.get_value(r, c) + 1) 

d1.rename(columns='count({})'.format).rename_axis('city').reset_index() 

Variation der ersten Lösung

from collections import Counter 

pd.Series(
    Counter(map(tuple, df.values.tolist())) 
).unstack(fill_value=0).rename(
    columns='count({})'.format 
).rename_axis('city').reset_index() 
+0

Vielen Dank! –