2017-01-20 108 views
2

考慮人員活動如下假設會計記錄在一家出版公司:分析:分總結記錄

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 
... 

假設蟒蛇熊貓分析框架,我們可以做到這一點依靠(主要是)對大熊貓的API,而不是做一個較低的水平,‘逐位’編程?這個查詢的問題是,每個記錄的「開始」和「結束」時間可能跨越數月(不只是一個月),所以這些記錄需要被「拆分」或「爆炸」成多個記錄每個期限爲一個月),然後我們可以使用通常的「groupby & sum」聚合來做最後的減少。

從未接受過SQL或數據庫方面的正式培訓,我不知道數據分析中是否有這樣的概念,所以我不知道正確的名稱。在Spark中,我認爲這可以完成,因爲RDD flatMap可以從單個元素中返回多個元素。

感謝, Wirawan

回答

0

首先,創建一個密集的長數據幀以每天每間開始日期和結束日期。爲此,熊貓有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