分析:拆分汇总记录

时间:2017-01-20 20:37:08

标签: python pandas analytics

考虑以下关于出版公司员工活动的假设会计记录:

Name          Activity        Begin-date       End-date
---------------------------------------------------------
Hasan         Proofreading    2015-01-27       2015-02-09
Susan         Writing         2015-02-01       2015-02-15
Peter         Editing         2015-01-01       2015-02-21
Paul          Editing         2015-01-24       2015-01-30
Stefan        Proofreading    2015-01-08       2015-01-08
...

这些代表每个人正在进行的活动,包括开始和结束日期(包含日期)。让我们说这家公司的高管想知道每个月在不同的活动中花了多少人工日。所需的报告可能如下所示:

Month        Activity          Man-hours
----------------------------------------
2015-01      Proofreading      720
2015-01      Editing           1283
2015-01      Writing           473
2015-02      Proofreading      1101
2015-02      Editing           893
2015-02      Writing           573
...

假设python Pandas分析框架,我们可以(大多数情况下)依赖熊猫吗? API,而不是低级别,"逐位"编程吗?这个查询的问题是"开始"和"结束"每条记录的时间可以跨越几个月(不仅仅是一个月),因此这些记录将需要分拆"或者#34;爆炸"分成多个记录(每个记录涵盖一个月),然后我们可以使用通常的" groupby&总和"聚合做最后的减少。

从未在SQL或数据库中接受过正式培训,我不知道数据分析中是否存在这样的概念,因此我不知道正确的名称。在Spark中,我认为可以做到这一点,因为RDD flatMap可以从单个元素中返回多个元素。

谢谢, Wirawan

1 个答案:

答案 0 :(得分:0)

首先,在每个开始日期和结束日期之间创建一个密集的长数据帧。为此,Pandas pd.date_range从两个日期生成DatetimeIndex。假设人们在周末工作,请让我们使用工作日频率,但您可以在其中使用任何有用的频率。

从这个范围我们用stack和一些索引重置进行了一些重新格式化。它导致:

df =(df.set_index(['name', 'activity'])
       .apply(lambda r : pd.Series(pd.date_range(r['begindate'],r['enddate'], freq='B')), 
              axis=1)
       .stack()
       .rename('date')
       .reset_index(level=-1, drop=True)
       .reset_index())
Out[73]: 
      name      activity       date
0    Hasan  Proofreading 2015-01-27
1    Hasan  Proofreading 2015-01-28
2    Hasan  Proofreading 2015-01-29
3    Hasan  Proofreading 2015-01-30
4    Hasan  Proofreading 2015-02-02
..     ...           ...        ...
10   Susan       Writing 2015-02-02
11   Susan       Writing 2015-02-03
..     ...           ...        ...

现在你可以进行每月聚合。将日期转换为每月期间并对其进行分组:

df.groupby(['activity',df.date.dt.to_period('M')]).size()
Out[97]: 
activity      date   
Editing       2015-01    27
              2015-02    15
Proofreading  2015-01     5
              2015-02     6
Writing       2015-02    10