Pandas DataFrame 中每月平均每日记录数
Average of daily count of records per month in a Pandas DataFrame
我有一个带有 TIMESTAMP
列的 pandas DataFrame,它是 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
这没问题,再做一些工作,我可以映射到结果以更正月份名称,然后绘制条形图。但是,我不确定这是否是 correct/best 方式,我怀疑使用 Pandas.
可能有更简单的方法来获取结果
很高兴听到您的想法。谢谢!
注意: 如果我没有将 TIMESTAMP 列设置为索引,我会收到 "reduction operation 'mean' not allowed for this dtype" 错误。
我认为您需要进行两轮 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
进行两个 groupby 并绘制每月平均计数:
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 轴的格式还有一些不足之处,但您可以根据需要进行调整。
我有一个带有 TIMESTAMP
列的 pandas DataFrame,它是 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
这没问题,再做一些工作,我可以映射到结果以更正月份名称,然后绘制条形图。但是,我不确定这是否是 correct/best 方式,我怀疑使用 Pandas.
可能有更简单的方法来获取结果很高兴听到您的想法。谢谢!
注意: 如果我没有将 TIMESTAMP 列设置为索引,我会收到 "reduction operation 'mean' not allowed for this dtype" 错误。
我认为您需要进行两轮 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
进行两个 groupby 并绘制每月平均计数:
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 轴的格式还有一些不足之处,但您可以根据需要进行调整。