Pandas DataFrame中每月记录日计数的平均值

6

我有一个pandas的DataFrame数据,其中包含一个TIMESTAMP列,其数据类型为datetime64。请注意,最初这一列不是索引;索引只是普通整数,前几行如下所示:

     TIMESTAMP                  TYPE
0    2014-07-25 11:50:30.640    2
1    2014-07-25 11:50:46.160    3
2    2014-07-25 11:50:57.370    2

每天都有任意数量的记录,有些天甚至没有数据。我需要得到的是每月平均每日记录数,然后绘制条形图,以月份为 x 轴(如2014年4月、2014年5月等)。我已经使用以下代码计算了这些值。

dfWIM.index = dfWIM.TIMESTAMP    
for i in range(dfWIM.TIMESTAMP.dt.year.min(),dfWIM.TIMESTAMP.dt.year.max()+1):
    for j in range(1,13):
        print dfWIM[(dfWIM.TIMESTAMP.dt.year == i) & (dfWIM.TIMESTAMP.dt.month == j)].resample('D', how='count').TIMESTAMP.mean()

以下是输出结果:

nan
nan
3100.14285714
6746.7037037
9716.42857143
10318.5806452
9395.56666667
9883.64516129
8766.03225806
9297.78571429
10039.6774194
nan
nan
nan

这段文本是可以的,经过一些处理,我可以将结果映射到正确的月份名称,然后绘制条形图。但是,我不确定这是否是正确/最佳的方法,我怀疑可能有更简单的方法使用Pandas获得结果。
如果我不将时间戳列设置为索引,则会出现“此dtype不允许平均值的缩减操作”错误。
请注意:
1个回答

10

我认为你需要进行两轮groupby操作,第一轮按天分组并计数,第二轮按月份分组并计算每日计数的平均值。你可以像这样做。

首先,我会生成一些类似于你的假数据:

import pandas as pd

# make 1000 random times throughout the year
N = 1000
times = pd.date_range('2014', '2015', freq='min')
ind = np.random.permutation(np.arange(len(times)))[:N]

data = pd.DataFrame({'TIMESTAMP': times[ind],
                     'TYPE': np.random.randint(0, 10, N)})
data.head()

输入图片描述

现在我将使用pd.TimeGrouper进行两个分组,并绘制每月平均计数:

import seaborn as sns  # for nice plot styles (optional)

daily = data.set_index('TIMESTAMP').groupby(pd.TimeGrouper(freq='D'))['TYPE'].count()
monthly = daily.groupby(pd.TimeGrouper(freq='M')).mean()
ax = monthly.plot(kind='bar')

输入图像描述

如果需要,你可以微调x轴的格式,因为它留下了一些不尽人意的地方。


1
我一开始没想到该如何使用 groupby,结果发现 TimeGrouper 是个好东西。非常感谢! - marillion
沿时间序列的柱形图在x轴方向上的格式化比我想象中要复杂得多。如果有人遇到了同样的问题,解决方案可以参考https://dev59.com/MZDea4cB1Zd3GeqPi_eG。 - marillion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接