我有一个与时间序列有关的问题,涉及如何针对归因于同一个人的多个案例沿水平轴绘制时间戳。让我解释一下:
让我们假设我们有杰森和佐治亚州。他们两个都在不同的情况下工作,这些情况在很大程度上具有以下潜在的“事件”:开始,暂停,继续,结束。许多情况下只有一个“开始”和“结束”,而其他情况还包括一个暂停-恢复间隔。在暂停一种情况下,用户可以处理另一种情况。我在Pandas DataFrame上获得了所有这些信息,并通过groupby
收集了用户和案例级别的信息。
可复制代码的示例数据(假设导入了pandas
和numpy
)
raw_data = {'user': ['Jason', 'Georgia', 'Jason', 'Jason', 'Georgia'],
'case': ['a', 'b', 'c', 'd', 'e'],
'date_picked_up': ['2018-10-25 14:06', '2019-01-25 10:44', '2019-01-25 09:14', '2019-01-25 12:12', '2019-02-21 10:01'],
'date_paused': ['2018-10-26 11:08', '2019-01-25 12:11', np.nan, np.nan, '2019-02-21 12:37'],
'date_resumed': ['2018-10-26 11:20', '2019-01-25 15:21', np.nan, np.nan, '2019-02-21 13:24'],
'date_closed': ['2018-10-29 16:57', '2019-01-25 16:34', '2019-01-25 11:46', '2019-01-25 15:24', '2019-01-25 13:56']}
df = pd.DataFrame(raw_data, columns = ['user', 'case', 'date_picked_up', 'date_paused', 'date_resumed', 'date_closed'])
df
这将返回df
,这是一个熊猫数据框架,其中包含每种情况的进展。如果没有暂停恢复间隔,则值为np.nan
。熊猫groupby
会自动忽略我们不希望的nan
值,因此,为了处理此问题,我将1900年的fillna
与Timestamp
一起使用后,列pd.to_datetime
:
date_cols = ['date_picked_up', 'date_paused', 'date_resumed', 'date_closed']
for c in date_cols:
df[c] = pd.to_datetime(df[c], format='%Y%m%d %H:%M')
现在,我发现按用户然后按情况汇总数据的最佳方法是:
df.fillna(pd.Timestamp('19000101'))\
.groupby(['user', 'case', 'date_picked_up', 'date_paused', 'date_resumed', 'date_closed'])[['date_picked_up', 'date_paused', 'date_resumed', 'date_closed']].count()
我的目标(来自此示例数据)是两个图,一个用于Jason,一个用于佐治亚州,其中时间戳(理想情况下不是1900年)将沿水平“线”显示,每种情况一个(在y上)轴)。最接近的示例是:Plotting labled time series in pandas,其中(对于Jason而言)在y轴上有a,c和d而不是狗,猫和牛。
我已经找到了有关如何将所有内容移到bokeh
或d3
的想法(例如:https://github.com/jiahuang/d3-timeline,How to plot stacked event duration (Gantt Charts) using Python Pandas?),但我希望找到Python和Matplotlib / Seaborn的解决方案,因为我相信我的数据结构已经足够好了。