因此,我有一个pandas数据框,其中包含大量列,其中一列是datetime格式的时间戳。数据框中的每一行代表一个“事件”。我要做的是绘制这些事件随时间变化的频率。基本上是一个简单的条形图,显示每月有多少事件。
以以下代码开头:
data.groupby([(data.Timestamp.dt.year),(data.Timestamp.dt.month)]).count().plot(kind = 'bar')
plt.show()
这种“种类”有效。但是有两个问题:
1)该图带有图例,该图例包括原始数据中的所有列(例如30多个列)。而且图形上的每个条形图都有一个很小的子条形图(每个列的值都相同,因为我只是在计算事件)。
2)在某些月份中,零事件发生。这些个月根本没有出现在图表上。
我终于想出了代码,使图形看起来像我想要的样子。但是在我看来,我并不是以“正确”的方式进行操作,因为这肯定是一个相当普遍的用例。
基本上,我创建了一个新数据框,其中有一列“ count”和一个索引,该索引用月/年的字符串表示。我在关心的时间范围内填充了零,然后将数据从第一帧复制到新帧。这是代码:
import pandas as pd
import matplotlib.pyplot as plt
cnt = data.groupby([(data.Timestamp.dt.year),(data.Timestamp.dt.month)]).count()
index = []
for year in [2015, 2016, 2017, 2018]:
for month in range(1,13):
index.append('%04d-%02d'%(year, month))
cnt_new = pd.DataFrame(index=index, columns=['count'])
cnt_new = cnt_new.fillna(0)
for i, row in cnt.iterrows():
cnt_new.at['%04d-%02d'%i,'count'] = row[0]
cnt_new.plot(kind = 'bar')
plt.show()
有人知道一种更简单的方法吗?
编辑->根据请求,以下是数据框类型的概念。它是来自SQL查询的结果。实际数据是我公司的……
Timestamp FirstName LastName HairColor \
0 2018-11-30 02:16:11 Fred Schwartz brown
1 2018-11-29 16:25:55 Sam Smith black
2 2018-11-19 21:12:29 Helen Hunt red
好的,我想我明白了。感谢Yuca提供的重采样命令。我只需要在Timestamp数据系列上运行它(而不是在整个数据帧上),它就可以为我提供我想要的东西。
> data.index = data.Timestamp
> data.Timestamp.resample('M').count()
Timestamp
2017-11-30 0
2017-12-31 0
2018-01-31 1
2018-02-28 2
2018-03-31 7
2018-04-30 9
2018-05-31 2
2018-06-30 6
2018-07-31 5
2018-08-31 4
2018-09-30 1
2018-10-31 0
2018-11-30 5
答案 0 :(得分:1)
所以OP请求是:“基本上是一个简单的条形图,显示每月有多少事件”
使用pd.resample
和每月一次的频率可获得预期的结果
df[['FirstName']].resample('M').count()
输出:
FirstName
Timestamp
2018-11-30 3
要包括未观察到的月份,我们需要创建一个基准日历
df_a = pd.DataFrame(index = pd.date_range(df.index[0].date(), periods=12, freq='M'))
然后将其重采样结果分配给它
df_a['count'] = df[['FirstName']].resample('M').count()
输出:
count
2018-11-30 3.0
2018-12-31 NaN
2019-01-31 NaN
2019-02-28 NaN
2019-03-31 NaN
2019-04-30 NaN
2019-05-31 NaN
2019-06-30 NaN
2019-07-31 NaN
2019-08-31 NaN
2019-09-30 NaN
2019-10-31 NaN