2013-04-09 85 views
1

我有一個multiindex數據框,包含不同地區,大小和日期的銷售數據。我想計算每個日期的「全球範圍內」(所有區域)銷售總額(按大小),然後將其分配到原始數據框中的一列,並將銷售額和規模的每個全球價值廣播到每個區域。我想我可以按大小和日期分組,然後cumsum(),然後採取答案,並將其重新索引到原始數據框,但這似乎不起作用。熊貓:reindex multiindex,播放結果

這裏的設置代碼:

import pandas as pd 
#Create the dataframe 'df' 
regions=['NorthAm']*9 
regions.extend(['APAC']*9) 
regions.extend(['Eur']*9) 
sizes=[12]*3 
sizes.extend([14]*3) 
sizes.extend([16]*3) 
sizes=sizes*3 
dates=['1/1/2011','1/2/2011','1/3/2011']*27 
idx=zip(regions,sizes,dates) 
idx=pd.MultiIndex.from_tuples(idx, names=['Region','Size','Date']) 
df=pd.DataFrame(np.arange(27), index = idx, columns=['Sales']) 

# Check it 
df 

Out[1]: 
         Sales 
Region Size Date   
NorthAm 12 1/1/2011  0 
      1/2/2011  1 
      1/3/2011  2 
     14 1/1/2011  3 
      1/2/2011  4 
      1/3/2011  5 
     16 1/1/2011  6 
      1/2/2011  7 
      1/3/2011  8 
APAC 12 1/1/2011  9 
      1/2/2011  10 
      1/3/2011  11 
     14 1/1/2011  12 
      1/2/2011  13 
      1/3/2011  14 
     16 1/1/2011  15 
      1/2/2011  16 
      1/3/2011  17 
Eur  12 1/1/2011  18 
      1/2/2011  19 
      1/3/2011  20 
     14 1/1/2011  21 
      1/2/2011  22 
      1/3/2011  23 
     16 1/1/2011  24 
      1/2/2011  25 
      1/3/2011  26 

# Yes, that's right. Now create the cumulative sum, regardless of region 
cs=df.groupby(level=['Size','Date']).sum().groupby(level=0).cumsum() 

# Check it. 
cs 

Out[1]: 
       Sales 
Size Date   
12 1/1/2011  27 
    1/2/2011  57 
    1/3/2011  90 
14 1/1/2011  36 
    1/2/2011  75 
    1/3/2011 117 
16 1/1/2011  45 
    1/2/2011  93 
    1/3/2011 144 

現在我願意做這樣的事情:

df['WWSales']=cd.reindex(df, method='???') 

得到的東西,如:

Out[2]: 
         Sales WWSales 
Region Size Date   
NorthAm 12 1/1/2011  0 27 
      1/2/2011  1 57 
      1/3/2011  2 90 
     14 1/1/2011  3 36 
      1/2/2011  4 75 
      1/3/2011  5 115 
     16 1/1/2011  6 45 
      1/2/2011  7 93 
      1/3/2011  8 144 
APAC 12 1/1/2011  9 27 
      1/2/2011  10 57 
      1/3/2011  11 90 
     14 1/1/2011  12 36 
      1/2/2011  13 75 
      1/3/2011  14 115 
     16 1/1/2011  15 45 
      1/2/2011  16 93 
      1/3/2011  17 144 
Eur  12 1/1/2011  18 27 
      1/2/2011  19 57 
      1/3/2011  20 90 
     14 1/1/2011  21 36 
      1/2/2011  22 75 
      1/3/2011  23 115 
     16 1/1/2011  24 45 
      1/2/2011  25 93 
      1/3/2011  26 144 

我懷疑有一些真的明顯的解決方案,但我沒有看到它(並沒有在搜索中找到它)。任何幫助將不勝感激。

順便說一下,一個優雅的方式使日期列成DateTimeIndex的獎勵點。下面的作品,但似乎不雅:

df.index.levels[2]=pd.tseries.period.DatetimeIndex(df.index.levels[2]) 

回答

3

相反的(隱含的)應用sumcumsum,使用對每個組的transform方法。那就是:

df['WWSales'] = df.groupby(level=['Size','Date']).transform(np.sum).groupby(level=0).transform(np.cumsum) 

這會給你想要的輸出。

http://pandas.pydata.org/pandas-docs/dev/groupby.html#transformation

我會在你的獎金問題採取一條縫:你可以映射到Timestamp您的列表。

dates = map(pd.Timestamp, ['1/1/2011','1/2/2011','1/3/2011']*27) 

但我希望有一個更合適的方法 - 我放棄了這個問題更有經驗的聲音....

+0

嗯。當我嘗試您的轉換建議時,我收到斷言錯誤。你有沒有嘗試過,並有它的工作?在你額外的信用上,我喜歡這個主意,並且會牢記在心。謝謝你的想法。 – msteen 2013-04-10 03:41:10

+0

我確實試過並讓它工作。我從IPython上貼上了這個。你使用哪種版本的熊貓? – 2013-04-10 15:27:18

+0

0.8.1。也許就是這樣。你的回答是對的,我只是沒有得到它在我的機器上工作。我會看看我是否可以解決問題。謝謝你的幫助! – msteen 2013-04-10 22:28:28