2017-01-25 32 views
1

我有一個關於熊貓Dataframes重採樣方法的問題。 我有每天一個觀察的數據框:熊貓Dataframe重採樣與特定日期

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randint(0,100,size=(366, 1)), columns=list('A')) 
df.index = pd.date_range(datetime.date(2016,1,1),datetime.date(2016,12,31)) 

,如果我要計算每月的總和(或其他),我可以直接做:

EOM_sum = df.resample(rule="M").sum() 

但是我有一個特定日曆(不規則頻率):

import datetime 
custom_dates = pd.DatetimeIndex([datetime.date(2016,1,13), 
          datetime.date(2016,2,8), 
          datetime.date(2016,3,16), 
          datetime.date(2016,4,10), 
          datetime.date(2016,5,13), 
          datetime.date(2016,6,17), 
          datetime.date(2016,7,12), 
          datetime.date(2016,8,11), 
          datetime.date(2016,9,10), 
          datetime.date(2016,10,9), 
          datetime.date(2016,11,14), 
          datetime.date(2016,12,19), 
          datetime.date(2016,12,31)]) 

如果我想計算每個週期的總和,我目前添加一個臨時列,每行屬於上述期間的結束,則p的df,通過一組來執行操作:

df["period"] = custom_dates[custom_dates.searchsorted(df.index)] 
custom_sum = df.groupby(by=['period']).sum() 

但是,這是非常骯髒,看起來不pythonic。在Pandas中是否有內置的方法? 在此先感謝。

+0

新列不是必需的,您可以使用'custom_sum = df.groupby(custom_dates [custom_dates.searchsorted(df.index)])。sum()' – jezrael

+0

熊貓重採樣方法基於使用頻率索引某種程度上。您使用的方法是正確的方法,請參閱上面的@jezrael的回答,以跳過添加的列 – James

+0

謝謝,我只是感到驚訝,因爲它與「重採樣」方法非常接近,所以Pandas中沒有這樣做。 – JMat

回答

0

創建NW列是沒有必要的,可以groupbyDatatimeIndex,因爲length是相同lenghtdf的:

import pandas as pd 
import numpy as np 

np.random.seed(100) 
df = pd.DataFrame(np.random.randint(0,100,size=(366, 1)), columns=list('A')) 
df.index = pd.date_range(datetime.date(2016,1,1),datetime.date(2016,12,31)) 
print (df.head()) 
      A 
2016-01-01 8 
2016-01-02 24 
2016-01-03 67 
2016-01-04 87 
2016-01-05 79 

import datetime 
custom_dates = pd.DatetimeIndex([datetime.date(2016,1,13), 
          datetime.date(2016,2,8), 
          datetime.date(2016,3,16), 
          datetime.date(2016,4,10), 
          datetime.date(2016,5,13), 
          datetime.date(2016,6,17), 
          datetime.date(2016,7,12), 
          datetime.date(2016,8,11), 
          datetime.date(2016,9,10), 
          datetime.date(2016,10,9), 
          datetime.date(2016,11,14), 
          datetime.date(2016,12,19), 
          datetime.date(2016,12,31)]) 
custom_sum = df.groupby(custom_dates[custom_dates.searchsorted(df.index)]).sum() 
print (custom_sum) 
       A 
2016-01-13 784 
2016-02-08 1020 
2016-03-16 1893 
2016-04-10 1242 
2016-05-13 1491 
2016-06-17 1851 
2016-07-12 1319 
2016-08-11 1348 
2016-09-10 1616 
2016-10-09 1523 
2016-11-14 1793 
2016-12-19 1547 
2016-12-31 664 

另一種解決方案是新index通過custom_dates追加,groupby使用numpy array作爲searchsorted的輸出功能:

print (custom_dates.searchsorted(df.index)) 
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 
    2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 
    2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
    3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
    4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 
    6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 
    7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 
    8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
    8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
    9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 
11 11 11 11 12 12 12 12 12 12 12 12 12 12 12 12] 

custom_sum = df.groupby(custom_dates.searchsorted(df.index)).sum() 
custom_sum.index = custom_dates 
print (custom_sum) 
       A 
2016-01-13 784 
2016-02-08 1020 
2016-03-16 1893 
2016-04-10 1242 
2016-05-13 1491 
2016-06-17 1851 
2016-07-12 1319 
2016-08-11 1348 
2016-09-10 1616 
2016-10-09 1523 
2016-11-14 1793 
2016-12-19 1547 
2016-12-31 664