2017-08-10 6 views
4

次のような構造のpandas DataFrameがあるとします。しかし、 の練習では、レベル1のインデックスの数とレベル2のインデックスの数(レベル1のインデックスごと)が異なるため、解決策ではこれを仮定しないでください。MultiIndex DataFrameの特定の場所にどのように挿入できますか?

index = pandas.MultiIndex.from_tuples([ 
    ("a", "s"), 
    ("a", "u"), 
    ("a", "v"), 
    ("b", "s"), 
    ("b", "u")]) 

result = pandas.DataFrame([ 
    [1, 2], 
    [3, 4], 
    [5, 6], 
    [7, 8], 
    [9, 10]], index=index, columns=["x", "y"]) 
このようになります

 x y 
a s 1 2 
    u 3 4 
    v 5 6 
b s 7 8 
    u 9 10 

は、今の私は、「a」および「b」のレベルごとに「合計」行を作成したいとしましょう。だから私は私のコードは、このような何かを作るしたい入力上記のように与えられた:

 x y 
a s 1 2 
    u 3 4 
    v 5 6 
    t 9 12 
b s 7 8 
    u 9 10 
b t 16 18 

ここで私がこれまで持っているコードです:

# Calculate totals 
for level, _ in result.groupby(level=0): 

    # work out the global total for that desk: 
    x_sum = result.loc[level]["x"].sum() 
    y_sum = result.loc[level]["y"].sum() 

    result = result.append(pandas.DataFrame([[x_sum, y_sum]], columns=result.columns, index=pandas.MultiIndex.from_tuples([(level, "t")]))) 

は、しかし、これは追加される「合計」欄に結果最後に:

 x y 
a s 1 2 
    u 3 4 
    v 5 6 
b s 7 8 
    u 9 10 
a t 9 12 
b t 16 18 

は私がやりたいことはありませんresult.sort_index()を使用して並べ替え、次のいずれか

 x y 
a s 1 2 
    t 9 12 
    u 3 4 
    v 5 6 
b s 7 8 
    t 16 18 
    u 9 10 

私は間違っていますか?

答えて

2

私に与えるが、sorted Multiindexの理由は、より良いパフォーマンスです。また、ソートされていない場合は、MultiIndexがあります。MultiIndexで選択する場合は、一部があります。

実際にラベルの位置を変更する必要がある場合は、reindexを使用することができます。

df = result.groupby(level=0).sum() 
df.index = [df.index, ['t'] * len(df.index)] 
df1 = pd.concat([result, df]).sort_index().reindex(['s','u','t'], level=1) 

df1 = pd.concat([result, df]).sort_index() 
print (df1) 
     x y 
a s 1 2 
    t 4 6 
    u 3 4 
b s 5 6 
    t 12 14 
    u 7 8 

df1 = df1.reindex(['s','u','t'], level=1) 
print (df1) 
     x y 
a s 1 2 
    u 3 4 
    t 4 6 
b s 5 6 
    u 7 8 
    t 12 14 

よりダイナミックな解決策:GroupBy.apply

print (result.index.get_level_values(1).unique().tolist()) 
['s', 'u'] 

df1 = df1.reindex(result.index.get_level_values(1).unique().tolist() + ['t'], level=1) 
print (df1) 
     x y 
a s 1 2 
    u 3 4 
    t 4 6 
b s 5 6 
    u 7 8 
    t 12 14 

カスタム関数でsetting with enlargementのもう一つの解決策:

def f(x): 
    x.loc[(x.name, 't'),:] = x.sum() 
    return x 

df = result.groupby(level=0, group_keys=False).apply(f) 
print (df) 
     x  y 
a s 1.0 2.0 
    u 3.0 4.0 
    t 4.0 6.0 
b s 5.0 6.0 
    u 7.0 8.0 
    t 12.0 14.0 
+0

レベル2インデックスの数が変更された場合、これはどのように機能しますか?私は私の質問でこれを言いましたが、その例で実際にそれを説明していないことに気がついたので、サンプルコードをレベル1のエントリ( "v")に調整しました。 – arman

+0

私は2番目の解決策が動作するはずだと思います。 – jezrael

+0

そうですね。ありがとうございました :) – arman

0
result.reindex(pandas.MultiIndex.from_tuples([ 
("a", "s"), 
("a", "u"), 
("a", "t"), 
("b", "s"), 
("b", "u"), 
("b", "t") 
])) 

はそれが本当にannoyningさ

 x y 
a s 1 2 
    u 3 4 
    t 4 6 
b s 5 6 
    u 7 8 
    t 12 14 
+0

感謝。これはおそらく動作しますが、実際の構造が実際のコードにどのようなものか分かりません(つまり、すべてのインデックス値を書き出すことはできません)。私はこれをもっと明確にしようとする問題を修正しました。 – arman

関連する問題