Pandas:将重采样与 groupby 相结合并计算时间差
Posted
技术标签:
【中文标题】Pandas:将重采样与 groupby 相结合并计算时间差【英文标题】:Pandas: Combine resampling with groupby and calculate time differences 【发布时间】:2013-04-24 22:54:37 【问题描述】:我正在使用交易数据进行数据分析。我想使用 Pandas 来检查交易者活跃的时间。
特别是,我尝试提取每个交易者每天的第一笔交易日期之间的分钟差,并将其累积到每月
数据如下:
Timestamp (Datetime) | Buyer | Volume
--------------------------------------
2012-01-01 09:00:00 | John | 10
2012-01-01 10:00:00 | Mark | 10
2012-01-01 16:00:00 | Mark | 10
2012-01-01 11:00:00 | Kevin | 10
2012-02-01 10:00:00 | Mark | 10
2012-02-01 09:00:00 | John | 10
2012-02-01 17:00:00 | Mark | 10
现在我每天都使用重采样来检索第一笔交易。但是,我还想按买方分组以计算他们交易日期的差异。像这样
Timestamp (Datetime) | Buyer | Volume
--------------------------------------
2012-01-01 09:00:00 | John | 10
2012-01-01 10:00:00 | Mark | 10
2012-01-01 11:00:00 | Kevin | 10
2012-01-02 10:00:00 | Mark | 10
2012-01-02 09:00:00 | John | 10
总体而言,我希望计算每个交易者每天首次交易之间的分钟数差异。
更新
例如在 2012 年 1 月 1 日 John 的情况下:Dist = 60 (Diff John-Mark) + 120 (Diff John-Kevin) = 180
如果有人知道如何做到这一点,我将不胜感激。
谢谢
【问题讨论】:
你能添加一些预期的输出吗? (例如,为您的示例手动创建它) 【参考方案1】:您的原始帧(重新采样的帧)
In [71]: df_orig
Out[71]:
buyer date volume
0 John 2012-01-01 09:00:00 10
1 Mark 2012-01-01 10:00:00 10
2 Kevin 2012-01-01 11:00:00 10
3 Mark 2012-01-02 10:00:00 10
4 John 2012-01-02 09:00:00 10
将索引设置为日期列,保留日期列
In [75]: df = df_orig.set_index('date',drop=False)
创建这个聚合函数
def f(frame):
frame.sort('date',inplace=True)
frame['start'] = frame.date.iloc[0]
return frame
按单个日期分组
In [74]: x = df.groupby(pd.TimeGrouper('1d')).apply(f)
在几分钟内创建差异
In [86]: x['diff'] = (x.date-x.start).apply(lambda x: float(x.item().total_seconds())/60)
In [87]: x
Out[87]:
buyer date volume start diff
date
2012-01-01 2012-01-01 09:00:00 John 2012-01-01 09:00:00 10 2012-01-01 09:00:00 0
2012-01-01 10:00:00 Mark 2012-01-01 10:00:00 10 2012-01-01 09:00:00 60
2012-01-01 11:00:00 Kevin 2012-01-01 11:00:00 10 2012-01-01 09:00:00 120
2012-01-02 2012-01-02 09:00:00 John 2012-01-02 09:00:00 10 2012-01-02 09:00:00 0
2012-01-02 10:00:00 Mark 2012-01-02 10:00:00 10 2012-01-02 09:00:00 60
这里是解释。我们使用 TimeGrouper 按日期进行分组,其中将帧传递给函数 f。然后,此函数使用一天中的第一个日期(此处需要排序)。您从条目上的日期中减去它以获得 timedelta64,然后将其按摩到分钟(由于一些 numpy 问题,现在这有点 hacky,在 0.12 中应该更自然)
感谢您的更新,我原本以为您想要每个买家的差异,而不是来自第一个买家,但这只是一个小调整。
更新:
要跟踪买家姓名(对应于开始日期),只需包括 它在函数 f
def f(frame):
frame.sort('date',inplace=True)
frame['start'] = frame.date.iloc[0]
frame['start_buyer'] = frame.buyer.iloc[0]
return frame
然后可以在最后进行分组:
In [14]: x.groupby(['start_buyer']).sum()
Out[14]:
diff
start_buyer
John 240
【讨论】:
嗨,杰夫,非常感谢。这正是我一直在寻找的。但是,您是对的,我也在尝试计算每个买家的差异(对于 Kevin:120 (John-Kevin) + 60 (Mark-John) = 180),最后将这些每日总和汇总为每月粒度(其中将适用于约翰 180 (2012-01-01) + 60 (2012-01-02) = 240)。你会怎么做? 我添加了一个更新,我认为它可以满足您的需求。此外,您可能需要按月将 Timegrouper 放在整个事情上以每月汇总,但应该是一个简单的扩展以上是关于Pandas:将重采样与 groupby 相结合并计算时间差的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 0.18.1 groupby 和多级聚合错误重新采样
使用 pandas GroupBy 和时间序列重采样的平均聚合
Python PANDAS:使用 Groupby 重新采样多元时间序列
Python/Pandas - 结合 groupby 平均值和最小值