我想让每个医院每天获得平均Number of Records
。
|Hospital|Date|Number of Records
0|Hospital B|2018-02-12 16:07:54.183|5
1|Hospital B|2018-02-12 16:07:54.200|5
2|Hospital B|2018-02-12 16:07:54.220|2
3|Hospital B|2018-02-12 16:07:54.240|2
4|Hospital B|2018-02-12 16:07:54.253|1
5|Hospital B|2018-02-19 14:04:03.927|4
6|Hospital A|2017-12-18 00:00:00|9
7|Hospital A|2017-12-26 00:00:00|6
8|Hospital A|2018-02-05 14:12:49.587000|7
#df1 = pd.read_clipboard(sep='|')
这对于df1.groupby(['Hospital','Date']).sum().reset_index().groupby('Hospital').mean()
来说很简单,但由于时间戳弄错了医院A的计算,这是不正确的。答案应该是9.5。
我可以通过截断日期来解决这个问题。
df1['Date'] = pd.to_datetime(df1['Date'])
df1['Date'] = df1['Date'].dt.date
df1.groupby(['Hospital', 'Date']).sum().reset_index().groupby('Hospital').mean()
Hospital A 7.333333
Hospital B 9.500000
我还试图用Grouper来解决这个问题,因为我不想“截断”我的日期以便以后分析,也不会创建额外的列来避免这种情况。令我惊讶的是,Grouper花了近2倍的时间。
df1.set_index('Date').groupby([pd.Grouper(freq='D'),'Hospital']).sum().\
dropna().groupby('Hospital').mean()
Hospital A 7.333333
Hospital B 9.500000
第一种方式为 100 loops, best of 3: 5.37 ms per loop
,Grouper为100 loops, best of 3: 10.7 ms per loop
。
我在这里正确使用了Grouper吗?也许这需要很长时间,因为Grouper在我用drop_na()
删除的索引中的日期之间创建了日期?
答案 0 :(得分:2)
您也可以使用日期值而不覆盖您拥有的数据:
day = pd.to_datetime(df1['Date']).dt.date
df1.groupby(['Hospital', day]).sum().reset_index().groupby('Hospital').mean()
Hospital A 7.333333
Hospital B 9.500000
我猜测Grouper
的性能问题就是你提到的,生成大量行只是为了以后丢弃它们。但是,使用to_datetime
解析日期会产生必要的性能影响。您可以尝试避免解析并简单地切片:
day = df1['Date'].str.slice(0, 10)
df1.groupby(['Hospital', day]).sum().reset_index().groupby('Hospital').mean()
Hospital A 7.333333
Hospital B 9.500000
我的机器似乎稍微快一点,虽然我不知道大型数据集是否仍然如此。
答案 1 :(得分:2)
像
这样的东西df.groupby(['Hospital', df.Date.str[:10]]).sum().mean(level=0)
Out[915]:
Number of Records
Hospital
Hospital A 7.0 7.333333
Hospital B 7.5 9.500000