2017-10-19 12 views
1

私は、2つのレベルの列インデックスを持つデータフレームを持っています。私は2つのキー(列)に異なる集約関数を持つ必要があります。しかし、自分のコードでエラーが発生しました。マルチレベルのデータフレームで複数の列に集計する方法複数レベルインデックス内の集計

dic1 = {('count', 'N.A.'): {Period('1993-01', 'M'): 0, 
    Period('1993-02', 'M'): 0, 
    Period('1993-03', 'M'): 0}, 
('count', 'No'): {Period('1993-01', 'M'): 1, 
    Period('1993-02', 'M'): 1, 
    Period('1993-03', 'M'): 1}, 
('count', 'Yes'): {Period('1993-01', 'M'): 0, 
    Period('1993-02', 'M'): 0, 
    Period('1993-03', 'M'): 0}, 
('sum', 'N.A.'): {Period('1993-01', 'M'): nan, 
    Period('1993-02', 'M'): nan, 
    Period('1993-03', 'M'): nan}, 
('sum', 'No'): {Period('1993-01', 'M'): 6.5820000000000007, 
    Period('1993-02', 'M'): 131.1865, 
    Period('1993-03', 'M'): 133.31049999999999}, 
('sum', 'Yes'): {Period('1993-01', 'M'): nan, 
    Period('1993-02', 'M'): nan, 
    Period('1993-03', 'M'): nan}} 

df1 = pd.DataFrame(dic1) 

df1.to_timestamp(how='end').groupby(pd.TimeGrouper('A')).agg(
{'count':['max', 'min', 'median', 'last'] , 
'sum':['mean', 'max' , 'last']}) 

error: KeyError: 'sum' 

enter image description here

答えて

1

あなたはグループ化の前に列マルチインデックスをフラット化できます。

df1 = pd.DataFrame(dic1) 
df2 = df1.to_timestamp(how='end') 
df2 = df2.rename_axis(['operation', 'YN'], axis=1) 
df3 = df2.stack(level='YN').reset_index('YN') 
# operation  YN count  sum 
# 1993-01-31 N.A.  0  NaN 
# 1993-01-31 No  1 6.5820 
# 1993-01-31 Yes  0  NaN 
# 1993-02-28 N.A.  0  NaN 
# 1993-02-28 No  1 131.1865 
# 1993-02-28 Yes  0  NaN 
# 1993-03-31 N.A.  0  NaN 
# 1993-03-31 No  1 133.3105 
# 1993-03-31 Yes  0  NaN 

YN列を( stack/reset_indexを呼び出すことによって)カラムにDEXレベル、あなたは、通常の方法で問題にアプローチすることができます


import numpy as np 
import pandas as pd 
Period = pd.Period 
nan = np.nan 

dic1 = {('count', 'N.A.'): {Period('1993-01', 'M'): 0, Period('1993-02', 'M'): 0, Period('1993-03', 'M'): 0}, ('count', 'No'): {Period('1993-01', 'M'): 1, Period('1993-02', 'M'): 1, Period('1993-03', 'M'): 1}, ('count', 'Yes'): {Period('1993-01', 'M'): 0, Period('1993-02', 'M'): 0, Period('1993-03', 'M'): 0}, ('sum', 'N.A.'): {Period('1993-01', 'M'): nan, Period('1993-02', 'M'): nan, Period('1993-03', 'M'): nan}, ('sum', 'No'): {Period('1993-01', 'M'): 6.5820000000000007, Period('1993-02', 'M'): 131.1865, Period('1993-03', 'M'): 133.31049999999999}, ('sum', 'Yes'): {Period('1993-01', 'M'): nan, Period('1993-02', 'M'): nan, Period('1993-03', 'M'): nan}} 

df1 = pd.DataFrame(dic1) 
df2 = df1.to_timestamp(how='end') 
df2 = df2.rename_axis(['operation', 'YN'], axis=1) 
df3 = df2.stack(level='YN').reset_index('YN') 

grouped = df3.groupby([pd.TimeGrouper('A'), 'YN']) 
result = grouped.agg(
    {'count':['max', 'min', 'median', 'last'], 'sum':['mean', 'max' , 'last']}) 
result = result.unstack('YN') 
print(result) 

利回り

  sum              count \ 
      mean     max    last     max 
YN   N.A.   No Yes N.A.  No Yes N.A.  No Yes N.A. 
1993-12-31 NaN 90.359667 NaN NaN 133.3105 NaN NaN 133.3105 NaN  0 

      ...            
      ...  min  median  last   
YN   ... Yes N.A. No Yes N.A. No Yes N.A. No Yes 
1993-12-31 ... 0 0 1 0  0 1 0 0 1 0 
+0

おかげ@感謝を! 'reset_index(-1)'はmake pandasが日付を繰り返すか、それとも他の機能を持っていますか? – Roo

+0

['reset_index'](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.reset_index.html)は、インデックスを移動します(または、マルチインデックスの場合、レベルMultiIndexの)をDataFrameの列に追加します。 'reset_index(-1)'は、MultiIndexの最後のレベルを列に移動します。この場合、 'YN'インデックスレベルを同じ名前の新しいカラムに移動します。 'reset_index(-1)'は、最後のレベルに名前がない場合に便利です。ここでは、 'reset_index( 'YN')'を使った方がいいでしょう。 – unutbu

+0

[stack](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.stack.html)は、列インデックス(または列MultiIndexのレベル)を行インデックスに移動します。一緒に、 'stack'の後に' reset_index'が続くと、カラムインデックスのレベルが新しいDataFrameカラムに移動します。 – unutbu

2

これを行うためのハック方法の一種で、それぞれすべてのカウントと合計列を引き出すことです。

In [11]: agg_dict = {col: ['mean', 'max' , 'median', 'last'] for col in df1.columns[df1.columns.get_level_values(0) == "count"]} 

In [12]: agg_dict.update({col: ['mean', 'max' , 'last'] for col in df1.columns[df1.columns.get_level_values(0) == "sum"]}) 

In [13]: g = df1.to_timestamp(how='end').groupby(pd.TimeGrouper('A')) 

In [14]: g.agg(agg_dict) 
Out[14]: 
      sum              count 
      N.A.     No      Yes   N.A.     No     Yes 
      mean max last  mean  max  last mean max last mean max median last mean max median last mean max median last 
1993-12-31 NaN NaN NaN 90.359667 133.3105 133.3105 NaN NaN NaN  0 0  0 0 1 1  1 1 0 0  0 0 
+0

ニースソリューション、アンディ・ヘイデン – Roo

関連する問題