2015-10-20 55 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