2015-10-20 246 views
4

這可能是一個兩部分問題,但我正在尋找對二級索引標識的記錄子集重新標定(或執行任何操作)的最佳方法。子集熊貓DataFrame二級索引和重新分配值

例如 - 說我有以下的數據幀:

>>> df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]), columns=['Var1','Var2','Var3']) 
>>> df.index.names=['Number','Letter'] 
>>> print df 
       Var1 Var2 Var3 
Number Letter     
1  a  1.0 2.00 3.00 
     b  0.4 0.50 0.60 
2  a  7.0 8.00 9.00 
     b  0.1 0.11 0.12 

我想通過字母「B」標識的兩個記錄有乘以10

第一個變量的所有3我正在努力的方面是如何選擇多索引的第二個索引。我可以用下面的工作馬虎,各地做到這一點,但我想像有一個更清潔的方式:

>>> df=df.reset_index().set_index(['Letter','Number']) 
>>> Records=df.loc['b'] 
>>> print Records 
     Var1 Var2 Var3 
Number     
1  0.4 0.50 0.60 
2  0.1 0.11 0.12 

任何建議上一個更好的方法進行子集在第二索引?

,然後我可以重新調節:

>>> print Records*10 
     Var1 Var2 Var3 
Number     
1   4  5  6 
2   10 11 12 

但是,我怎麼那麼這些新近重新調整值替換原有的值?

回答

2

隨着熊貓,你可以訪問第二個級別l在一個多指標有兩種:

df.loc[df.index.isin("b", level="Letter")] 
       Var1 Var2 Var3 
Number Letter     
1  b  0.4 0.50 0.60 
2  b  0.1 0.11 0.12 

df.xs("b", level="Letter") 
     Var1 Var2 Var3 
Number     
1  0.4 0.50 0.60 
2  0.1 0.11 0.12 

它不是完全一樣的輸出,而只有第一個版本將允許您的值(感謝更改爲loc和你保持這樣的事實所有的索引值):

df.loc[df.index.isin("b", level="Letter")] = df.loc[df.index.isin("b", level="Letter")]*10 

df 
       Var1 Var2 Var3 
Number Letter     
1  a   1 2.0 3.0 
     b   4 5.0 6.0 
2  a   7 8.0 9.0 
     b   1 1.1 1.2 

有了這一點,你也可以輕鬆地訪問給定列,你可以修改,以及:

df.loc[df.index.isin("b", level="Letter"), "Var3"] = "Foo" 
df 

       Var1 Var2 Var3 
Number Letter     
1  a   1 2.0 3 
     b   4 5.0 Foo 
2  a   7 8.0 9 
     b   1 1.1 Foo 

希望這有助於

1

規模由10倍的值,如果第二個指數水平是'b'

In [82]: 

print pd.DataFrame(data=df.values*np.where(df.index.get_level_values(1) == 'a', 1, 10).reshape((-1,1)), 
        index=df.index) 
       0 1 2 
Number Letter    
1  a  1 2.0 3.0 
     b  4 5.0 6.0 
2  a  7 8.0 9.0 
     b  1 1.1 1.2 

或者:

In [94]: 

print (df.T * np.where(df.index.get_level_values(1) == 'a', 1, 10)).T 
       Var1 Var2 Var3 
Number Letter     
1  a   1 2.0 3.0 
     b   4 5.0 6.0 
2  a   7 8.0 9.0 
     b   1 1.1 1.2 
1

我會去通過拆散,使多指標水平首先,然後切片:

In [72]: df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]),   columns=['Var1','Var2','Var3'])   

    In [73]: df 
    Out[73]: 
     Var1 Var2 Var3 
    1 a 1.0 2.00 3.00 
     b 0.4 0.50 0.60 
    2 a 7.0 8.00 9.00 
     b 0.1 0.11 0.12 

    In [89]: df1 = df.unstack(-2) # the same as level=0 
    In [90]: df1 
    Out[90]: 
     Var1  Var2  Var3  
      1 2  1  2  1  2 
    a 1.0 7.0 2.0 8.00 3.0 9.00 
    b 0.4 0.1 0.5 0.11 0.6 0.12 

    In [91]: df1.loc['a']*=10 
    In [92]: df1 
    Out[92]: 
     Var1  Var2   Var3  
      1  2  1  2  1  2 
    a 10.0 70.0 20.0 80.00 30.0 90.00 
    b 0.4 0.1 0.5 0.11 0.6 0.12 

    df = df1.stack().swaplevel(0,1) # return back to the multi-index 
+1

'df1.stack()。Swaplevel爲(0,1)'? – leroyJr

+0

是的,這是選項。添加到我的答案。謝謝。 – pausag