如何按时间聚合DataFrame并统计各城市的数量?
如何按时间统计各城市的出现次数
你现在遇到的问题是,普通的groupby+count只能算出每个时间点的总记录数,但没法拆分到具体城市。要得到你想要的分城市统计结果,其实用数据透视/交叉统计的方法就可以轻松实现,下面给你几种实用的方案:
方法1:使用pivot_table(最灵活通用)
pivot_table是Pandas里专门用来做数据透视的工具,正好匹配你的需求:
import pandas as pd # 假设你的DataFrame是df result = df.pivot_table( index='time', # 行索引用time列 columns='city', # 列用city的不同取值 aggfunc='size', # 统计出现次数 fill_value=0 # 没有数据的位置填0(可选,让结果更完整) ).add_suffix('_count') # 给列名加上_count后缀,匹配你的预期格式 result = result.reset_index() # 把time从索引变回普通列
运行后就能得到和你预期完全一致的结果:
time sydney_count melbourne_count 0 2018-05-8 2 1 1 2018-05-9 1 1
方法2:使用crosstab(专门的交叉统计函数)
如果只是单纯做计数的交叉统计,pd.crosstab会更简洁:
result = pd.crosstab(df['time'], df['city']).add_suffix('_count').reset_index()
这个函数默认就是统计两个列的交叉出现次数,代码更短,效果和上面一样。
方法3:基于你原来的groupby思路改进
如果你想沿用最初的分组思路,可以先统计每个时间组内各城市的数量,再把结果展开成列:
result = df.groupby('time')['city'].value_counts()\ .unstack(fill_value=0)\ .add_suffix('_count')\ .reset_index()
这里value_counts()会在每个时间组内统计各城市的出现次数,unstack()把城市从行索引转成列,再做后续的格式调整。
为什么你原来的方法得不到预期结果?
你之前用的df.groupby('time').agg({'city': 'count'}),这里的count是统计每个分组内非空记录的总数,不管city的具体取值是什么,所以得到的是每个时间点的总记录数,而不是分城市的计数。
内容的提问来源于stack exchange,提问作者timothyylim
相关产品推荐
相关产品推荐

