2013-04-30 58 views
2

我正在用交易数据进行数据分析。我想用熊猫来检查交易者活跃的时间。熊猫:将重采样与groupby结合并计算时差

特别是,我尝试提取的差异在每个交易者对每一天的每一个第一次交易的日期之间分钟,并累积按月

的数据是这样的:

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-01-01的情况下:距离= 60(DIFF约翰唛)+ 120(DIFF约翰 - 凯文)= 180

我如果有人有一个想法如何做到这一点,将高度赞赏。

谢谢

+0

你能添加一些预期的输出吗? (例如,为你的例子手动创建) – Jeff 2013-04-30 22:49:02

回答

3

你的原始帧(重采样一个)

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 

GROUPBY单日

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 

然后可以在年底这个GROUPBY:

In [14]: x.groupby(['start_buyer']).sum() 
Out[14]: 
      diff 
start_buyer  
John   240 
+0

嗨,杰夫,非常感谢。这正是我所期待的。然而,你是对的,我也试图计算每个买家的差异(这将是凯文:120(约翰 - 凯文)+60(马克 - 约翰)= 180),并最终将这些每日总和汇总为每月粒度约翰180(2012-01-01)+ 60(2012-01-02)= 240)。你会如何做到这一点? – Andy 2013-05-01 13:22:38

+0

我添加了一个更新,我认为这是你想要的。此外,您可能需要每月在整个事件上设置一个TimeGrouper,以便每月进行汇总,但应该是一个简单的扩展 – Jeff 2013-05-01 13:31:22