Python Pandas groupby多列

时间:2017-03-07 06:52:19

标签: python pandas data-analysis

谢谢你的帮助。

我的数据如下:

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

我希望我的最终结果如下:

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

我按城市分组,我想显示每个城市中每个room_type的数量。

用python pandas做任何事吗?谢谢。

我在几年前学过SQL并认为它可能已经成为可能。我确定python可以做同样的事情。谢谢!

2 个答案:

答案 0 :(得分:5)

您可以将crosstabrename列一起使用:

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

使用groupbysizevalue_counts进行重塑的其他解决方案unstack

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

答案 1 :(得分:2)

解决方案jezrael没有给出; - )

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

更多参与

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

第一种解决方案的变化

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