2016-06-21 78 views
0

我有一个DataFrame,我构建了一个双重索引。 “开始”值不存在于“结束”索引值中,反之亦然。熊猫可互换双重索引?

c_weights.rename(columns={0:'start',1:'end',2:'metric',3:'angular',4:'special',5:'cos_pi'}, inplace=True) 
c_weights.set_index(['start','end'],inplace=True) 
c_weights.head() 

df head()

我还想能够调用类似: c_weights.loc [1638]或c_weights.loc [638,1],并得到相同的数据线。为了说清楚,这两个索引组合总是唯一的。 这可以是骨骼吗?

+0

也许这是简化您的索引更容易。替代方案可以是:'c_weights.loc [(c_weights.index.get_level_values('start')== 1)&(c_weights.index.get_level_values('end')== 638)]' – kikocorreoso

+0

是不是疯狂的cpu昂贵?它将被用于循环。 – OHTO

+0

是的,它很贵。这就是为什么如果不重复,简化索引可能更好:-) – kikocorreoso

回答

0

一个数据帧是围绕numpy的ndarray,其中的行和列的索引被分配的包装。我们可以用不同的行或列索引定义第二个数据帧并访问相同的ndarray。例如,我们首先定义df1,然后用相同的数据定义df2,但交换MultiIndex行索引中的级别。保留相同的列。

import pandas as pd 
import numpy as np 

np.random.seed([3,1415]) 

df1 = pd.DataFrame(np.random.rand(4, 2), 
        pd.MultiIndex.from_product([('a', 'b'), (1, 2)]), 
        ['col1', 'col2']) 
df2 = pd.DataFrame(df1.values, df1.index.swaplevel(0, 1), df1.columns) 

print df1 

     col1  col2 
a 1 0.444939 0.407554 
    2 0.460148 0.465239 
b 1 0.462691 0.016545 
    2 0.850445 0.817744 

print df2 

     col1  col2 
1 a 0.444939 0.407554 
2 a 0.460148 0.465239 
1 b 0.462691 0.016545 
2 b 0.850445 0.817744 

我们可以看到数据是一样的,索引被交换。从df1访问数据与从df1到共同可变点的数据相同。让我们改变的东西在df1df2

df1.loc[('a', 1), 'col1'] = 1. 
print df2 

     col1  col2 
1 a 1.000000 0.407554 
2 a 0.460148 0.465239 
1 b 0.462691 0.016545 
2 b 0.850445 0.817744 

看现在,我们深信,让我们看到,我们现在有2个dataframes从中我们可以访问相同的数据。让我们定义一个函数来完成OP要求的功能。

ambigui_t = lambda t: df1.loc[t] if t in df.index else df2.loc[t] 

print ambigui_t(('a', 1)) 

col1 1.000000 
col2 0.407554 
Name: (a, 1), dtype: float64 

print ambigui_t((1, 'a')) 

col1 1.000000 
col2 0.407554 
Name: (1, a), dtype: float64 
+0

这一点,如果你认为没有改变过,其重塑或修改数据造成的副本 – Jeff

+0

该解决方案无论是框架做出只会工作做得更快,给一个清洁度值作为回答: l =(638,1) z在范围内的时间(1000):(c_weights.ix [[x for c_weights.index if(x == 1)or(x == l [:: - 1])]])。cos_pi CPU时间:用户32.7 s,sys:54。7毫秒,总:32.8小号 墙时间:32.8小号 %的时间在范围Z(1000):ambigui_t(升).cos_pi CPU时间:用户250毫秒,SYS:9.93毫秒,总:260毫秒 墙时间:254毫秒 – OHTO

0

不管怎么说,对于第一种情况,你可以使用ix和传递一个元组的行索引

c_weights.ix[(1,638)] 

对于第二种情况指标,我想这将取决于你是否知道断手或不如果你试图首先传递结束,那么我只需要以正确的方式构造一个元组或者反转它((638,1)[::-1] = (1, 638)

为了达到你的观点:既然你说你有互斥的开始和最后,还可以使用以下列表理解

l = (start, end) # l = (end, start) returns the same 
c_weights.ix[[x for x in c_weights.index if (x == l) or (x == l[::-1])]] 

如果你也有唯一索引,可以简化这:

c_weights.ix[[x for x in c_weights.index if (x[0] == l[0]) or (x[1] == l[1])]] 
+0

这给出了一个答案,所以谢谢!,但它很慢。答案也可以这样回答:(c_weights.ix [[x for c_weights.index if(x == 1)或(x == 1 [:: - 1])]]])。cos_pi #### # 起始端 1 638 0.512143 名称:cos_pi,D型:float64 – OHTO