2013-10-17 26 views
8

我有兩個dataframes樞軸就像這樣:熊貓:這看起來與多指標數據

rating 
    BMW Fiat Toyota 
0 7  2  3 
1 8  1  8 
2 9 10  7 
3 8  3  9 

own 
    BMW Fiat Toyota 
0 1  1  0 
1 0  1  1 
2 0  0  1 
3 0  1  1 

我最終想要得到的透視表由品牌意味着評級使用 。或者是這樣的:

  BMW Fiat Toyota 
Usage       
0  8.333333 10  3 
1  7.000000  2  8 

我的方法是合併這樣的數據集:

Measure Rating    Own    
Brand  BMW Fiat Toyota BMW Fiat Toyota 
0    7  2  3 1  1  0 
1    8  1  8 0  1  1 
2    9 10  7 0  0  1 
3    8  3  9 0  1  1 

,然後嘗試使用評級作爲值來創建一個數據透視表,自己作爲行和品牌作爲列。但我一直在關注關鍵問題。我也嘗試拆分度量或品牌級別,但似乎無法將行索引名稱用作樞軸鍵。

我在做什麼錯?有沒有更好的方法呢?

回答

4

我不是大熊貓專家,因此該解決方案可能會比你想要更多的笨拙,但是:

rating = pd.DataFrame({"BMW":[7, 8, 9, 8], "Fiat":[2, 1, 10, 3], "Toyota":[3, 8, 7,9]}) 
own = pd.DataFrame({"BMW":[1, 0, 0, 0], "Fiat":[1, 1, 0, 1], "Toyota":[0, 1, 1, 1]}) 

r = rating.unstack().reset_index(name='value') 
o = own.unstack().reset_index(name='value') 
res = DataFrame({"Brand":r["level_0"], "Rating": r["value"], "Own": o["value"]}) 
res = res.groupby(["Own", "Brand"]).mean().reset_index() 
res.pivot(index="Own", columns="Brand", values="Rating") 

# result 
# Brand  BMW Fiat Toyota 
# Own       
# 0  8.333333 10  3 
# 1  7.000000  2  8 

另一種解決方案,雖然不是很普及(你可以使用循環,但你必須知道哪些值你有own數據幀):

d = [] 
for o in (0, 1): 
    t = rating[own == o] 
    t["own"] = o 
    d.append(t) 

res = pd.concat(d).groupby("own").mean() 
+0

謝謝。很高興有一個解決方案。你說得對,我希望有更優雅的東西,但是一個解決方案可以阻止我。我總是可以寫一個函數。 –

+0

@Brendon我想花費盡可能多的時間,因爲我現在可以學習熊貓,將會看到我可以在一週或兩週後做些什麼:)請不要接受答案,可能有些大師會用超級解決方案抵達 –

+0

那麼,你的個​​人資料上的標語說的太多:)。我會推遲一週接受你的答案。再次感謝。 –

3

我有一個新的答案,以我自己的問題(根據羅馬最初的答案)。關鍵是要獲得所需維度的索引。例如

rating.columns.names = ["Brand"] 
rating.index.names = ["n"] 
print rating 

Brand BMW Fiat Toyota 
n      
0  7  2  3 
1  8  1  8 
2  9 10  7 
3  8  3  9 

own.columns.names = ["Brand"] 
own.index.names = ["n"] 
print own 

Brand BMW Fiat Toyota 
n      
0  1  1  0 
1  0  1  1 
2  0  0  1 
3  0  1  1 

merged = pd.merge(own.unstack().reset_index(name="Own"), 
        rating.unstack().reset_index(name="Rating")) 
print merged 

    Brand n Own Rating 
0  BMW 0 1  7 
1  BMW 1 0  8 
2  BMW 2 0  9 
3  BMW 3 0  8 
4  Fiat 0 1  2 
5  Fiat 1 1  1 
6  Fiat 2 0  10 
7  Fiat 3 1  3 
8 Toyota 0 0  3 
9 Toyota 1 1  8 
10 Toyota 2 1  7 
11 Toyota 3 1  9 

然後可以很容易地使用pivot_table命令把它變成了期望的結果:

print merged.pivot_table(rows="Brand", cols="Own", values="Rating") 

Own    0 1 
Brand    
BMW  8.333333 7 
Fiat 10.000000 2 
Toyota 3.000000 8 

而這正是我一直在尋找。再次感謝羅馬指出的方式。