2016-07-25 74 views
2

我有存儲日期範圍和一些相關的colums一個大熊貓數據幀上的行子集總結:加入,並在數據幀

 date_start date_end ... lots of other columns ... 
1  2016-07-01 2016-07-02 
2  2016-07-01 2016-07-03 
3  2016-07-01 2016-07-04 
4  2016-07-02 2016-07-07 
5  2016-07-05 2016-07-06 

和日期索引皮卡丘目擊另一個數據框:

   pikachu_sightings 
     date 
2016-07-01     2 
2016-07-02     4 
2016-07-03     6 
2016-07-04     8 
2016-07-05     10 
2016-07-06     12 
2016-07-07     14 

對於第一個df中的每一行,我想計算該日期範圍內(即,date_startdate_end)內的皮卡丘的總和並將其存儲在新列中。所以最終會得到這樣的DF(左數爲清楚起見):

 date_start date_end total_pikachu_sightings 
1  2016-07-01 2016-07-02      2 + 4 
2  2016-07-01 2016-07-03     2 + 4 + 6 
3  2016-07-01 2016-07-04    2 + 4 + 6 + 8 
4  2016-07-02 2016-07-07 4 + 6 + 8 + 10 + 12 + 14 
5  2016-07-05 2016-07-06     10 + 12 

如果我這樣做迭代我會遍歷日期範圍的表的每一行,選擇行的子集

for range in ranges.itertuples(): 
    sightings_in_range = sightings[(sightings.index >= range.date_start) & (sightings.index <= range.date_end)] 
    sum_sightings_in_range = sightings_in_range["pikachu_sightings"].sum() 
    ranges.set_value(range.Index, 'total_pikachu_sightings', sum_sightings_in_range) 

這是我用熊貓的嘗試,但失敗,因爲這兩個dataframes的長度:但是這是方式對我的數據集太慢 - 匹配日期範圍,並對其執行之目擊報告表不匹配(即使他們這樣做,我的方法可能還有其他一些缺陷):

range["total_pikachu_sightings"] = 
    sightings[(sightings.index >= range.date_start) & (sightings.index <= range.date_end) 
      ["pikachu_sightings"].sum() 

我試圖理解一般方法/設計應該看起來像我想與其他函數聚合一樣,sum看起來像是最簡單的例子。對不起,如果這是一個明顯的問題 - 我是熊貓新手!

回答

1

首先確保pikachu_sightings具有日期時間索引並進行排序。

p = pikachu_sightings.squeeze() # force into a series 
p.index = pd.to_datetime(p.index) 
p = p.sort_index() 

然後確保你date_startdate_end的日期時間。

df.date_start = pd.to_datetime(df.date_start) 
df.date_end = pd.to_datetime(df.date_end) 

那麼它只是

df.apply(lambda x: p[x.date_start:x.date_end].sum(), axis=1) 

0  6 
1 12 
2 20 
3 54 
4 22 
dtype: int64 
+0

感謝這是一個優雅的解決方案,並且很有用!最後一行中的代碼是否還在使用熊貓?我問,因爲它對於一個大型數據集來說確實很慢(對於50,000個日期範圍是30秒,在皮卡丘購物中是6000行 - 並且想要處理更大的數據集!) – Matt

+0

@Matt它是熊貓。沒有矢量化。 – piRSquared

2

矢量化解決方案的草圖:

開始了p在piRSquared的答案。

確保date_的cols有datetime64 dtypes,即:

df['date_start'] = pd.to_datetime(df.date_time) 

然後計算累計總和:

psums = p.cumsum() 

result = psums.asof(df.date_end) - psums.asof(df.date_start) 

這還不是結束,雖然。 asof返回最後一個良好的值,所以它有時會採取確切的開始日期,有時不會(取決於您的數據)。所以,你必須對此進行調整。 (如果日期頻率爲day,那麼可能會將小時向後移動p的索引,例如-pd.Timedelta(1, 'h'),然後再添加p.asof(df.start_date)可能會有用。)