2016-12-06 85 views
2

我想在熊貓中做一個看起來很明顯的計算,但經過多次嘗試後,我沒有找到正確的方法。根據大熊貓的行值劃分一個列

我有一個數據幀,看起來像這樣:

df = pd.DataFrame([["A", "a", 10.0], 
        ["A", "b", 12.0], 
        ["A", "c", 13.0], 
        ["B", "a", 5.0 ], 
        ["B", "b", 6.0 ], 
        ["B", "c", 7.0 ]]) 

第一列是一個測試名稱,第二列是一個類,第三列給出的時間。每個測試通常在3個班的表中。

這是畫出像這樣正確的格式:

sns.factorplot(x="2", y="0", hue="1", data=df, 
       kind="bar") 

所以每一次測試,我得到一組的3個酒吧,一個爲每個類。

但是我想更改數據框,以便第2列中的每個值不是絕對值,而是與類「a」相比的比率。

所以我想將它轉換成這樣:

df = pd.DataFrame([["A", "a", 1.0], 
        ["A", "b", 1.2], 
        ["A", "c", 1.3], 
        ["B", "a", 1.0], 
        ["B", "b", 1.2], 
        ["B", "c", 1.4]]) 

我能提取系列,改變索引,使它們匹配,執行計算,例如:

df_a = df[df[1] == "a"].set_index(0) 
df_b = df[df[1] == "b"].set_index(0) 
df_b["ratio_a"] = df_b[2]/df_a[2] 

但是這肯定是非常低效的,我需要將它歸爲這種格式。

什麼是正確的做法?

回答

2

您還可以使用一些指數對準做到這一點。

df1 = df.set_index(['test', 'class']) 
df1/df1.xs('a', level='class') 

但變換是更好

+0

謝謝,這工作正常! – Dric512

4

你可以使用groupby/transform('first')找到每個組中的第一個值:

import pandas as pd 
df = pd.DataFrame([["A", "a", 10.0], 
        ["A", "b", 12.0], 
        ["A", "c", 13.0], 
        ["B", "b", 6.0 ], 
        ["B", "a", 5.0 ], 
        ["B", "c", 7.0 ]]) 
df = df.sort_values(by=[0,1]) 
df[2] /= df.groupby(0)[2].transform('first') 

產生

0 1 2 
0 A a 1.0 
1 A b 1.2 
2 A c 1.3 
3 B a 1.0 
4 B b 1.2 
5 B c 1.4 
+0

這是一件好事。 'df.groupby(0)[2] .transform(lambda x:x/x.iloc [0])'也應該很好,我想呢? – Zero

+0

@JohnGalt:像'transform('first')'這樣的「內置」函數是Cythonized的,所以它們比使用'lambda x:x/x.iloc [0]'等定製函數進行轉換要快得多。但是,是的,它會產生相同的結果。 – unutbu

+0

這看起來不錯。爲了保證「第一個」是正確的標籤,我應該首先按第1列對數據框進行排序嗎? – Dric512