2014-08-30 148 views
1

我想計算每個羣組每週的最大值,並在熊貓中創建一個包含這些值的新列。我在posted一個類似的問題,沒有解決我的問題,所以我重構了這個問題。從日期時間範圍和熊貓羣體計算的列

考慮使用時間戳,組和值列的數據幀:

datetime  group value 
2014-05-07 A  3 
2014-05-07 B  4 
2014-05-14 A  4 
2014-05-14 B  2 
2014-05-15 A  6 
2014-05-15 B  4 
2014-05-16 A  7 
2014-05-16 B  10 

我想與組每週最大值創建新列:

datetime  group value maxval 
2014-05-07 A  3  3 
2014-05-07 B  4  4 
2014-05-14 A  4  7 
2014-05-14 B  2  10 
2014-05-15 A  6  7 
2014-05-15 B  4  10 
2014-05-16 A  7  7 
2014-05-16 B  10  10 

在鏈接的問題,所提出的解決方案是轉換一個groupby子句,然後將其附加到數據框,但是這會造成系列中的排序錯誤。

回答

2

您可以transform組索引上都group,同時周:

>>> week = pd.DatetimeIndex(df.datetime).week 
>>> df["maxval"] = df.groupby(['group', week])["value"].transform('max') 
>>> df 
    datetime group value maxval 
0 2014-05-07  A  3  3 
1 2014-05-07  B  4  4 
2 2014-05-14  A  4  7 
3 2014-05-14  B  2  10 
4 2014-05-15  A  6  7 
5 2014-05-15  B  4  10 
6 2014-05-16  A  7  7 
7 2014-05-16  B  10  10 

請注意,如果您有多個年,這將每年的第二週(例如)合併到同組。

有時候人們會這麼想,但如果你不這樣做,你可以用同樣的方法將年份加到分組數量上。


如果你想,而不是滾動最大,你可以使用(恰如其分)rolling_max。您可以重新取樣自己或讓rolling_max做到這一點,像

def rolling_max_week(x): 
    rolled = pd.rolling_max(x, 7, min_periods=1, center=True, freq='d') 
    match_x = rolled.loc[x.index] 
    return match_x 

df["datetime"] = pd.to_datetime(df["datetime"]) 
df = df.set_index("datetime") 
df["rolling_max"] = df.groupby("group")["value"].transform(rolling_max_week) 
df["bin_max"] = df.groupby(["group", df.index.week])["value"].transform(max) 

現在,因爲它發生,這兩個產生於你的樣品完全相同的輸出:

>>> df 
      group value rolling_max bin_max 
datetime          
2014-05-07  A  3   3  3 
2014-05-07  B  4   4  4 
2014-05-14  A  4   7  7 
2014-05-14  B  2   10  10 
2014-05-15  A  6   7  7 
2014-05-15  B  4   10  10 
2014-05-16  A  7   7  7 
2014-05-16  B  10   10  10 

,但不會是一般來說是真的。您需要閱讀rolling_max的文檔,並嘗試使用一些測試用例,以確保我能正確解釋您想要的內容。

+0

如果我想從每天中選擇一週,該怎麼辦?例如,將一天當作中間一週,並且在三天之前和三天之後進行? – camdenl 2014-08-30 17:06:14

+0

我不知道我關注。你是否試圖(1)將一週的定義改變幾天,或者(2)你想要一個滾動窗口,以便每天有不同的一週,我們正在取得最大的結果? – DSM 2014-08-30 17:11:48

+0

一個移動的窗口,每天都有一個不同的星期,以當天爲中位數。 – camdenl 2014-08-30 17:16:43