2016-06-21 95 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