2017-08-10 58 views
4

假設我在結構中有一個類似於以下內容的熊貓數據框。然而,在 的實踐中,它可能會更大,第一級索引的數量以及第二級索引的數量(每級別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

這實在是annoyning,但原因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 

更動態的解決方案:

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另一種解決方案與GroupBy.apply

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

如果二級索引的數量發生變化,這將如何工作?我在我的問題中提到了這一點,但意識到這個例子沒有真正說明它,所以我已經調整了示例代碼以具有額外的1級條目(「v」)。 – arman

+0

我認爲第二個解決方案應該可以工作。 – jezrael

+0

是的,你說得對。謝謝 :) – arman

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

給我

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

感謝。這可能會工作,但我不知道實際結構是什麼在我的真實代碼(即我不能只寫出所有的索引值)。我已經修改了這個問題,試圖讓這個更清楚。 – arman

相關問題