2013-05-04 60 views
1

我有兩個數據框具有相同的列和索引。我想將它們合併到具有分層索引的第三個數據框中,維護當前的索引並添加第二個數據表明每個DataFrame的來源。這是我的嘗試:從現有的DataFrames構建分層索引的DataFrame

df_a = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 
df_b = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 
tuples = list(itertools.product(["a", "b"], range(3))) 
df = pd.DataFrame(columns=["x", "y"], index=pd.MultiIndex.from_tuples(tuples)) 
df.loc["a"] = df_a 
df.loc["b"] = df_b 

然而,df仍然充滿NaNs,當我預期得到與值從df_adf_b填寫。這確實工作:

df.loc["a"] = np.array(df_a) 

,但似乎都迂迴和錯誤。

我對層級索引有什麼不瞭解?什麼是實現我的目標的最佳方式?

回答

2
In [1]: df_a = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 

In [2]: df_b = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 

In [3]: pd.concat([df_a, df_b], keys=['a', 'b']) 
Out[3]: 
      x   y 
a 0 0.913812 -1.719241 
    1 0.544462 0.845426 
    2 -0.269518 -1.549679 
b 0 0.534311 1.693824 
    1 0.119147 -0.171002 
    2 0.595658 0.588252 
1

的另一種方法來實現這個,而不是填充數據幀df,是多索引添加到原始陣列df_adf_b),然後它們串聯(見下文)。

原因df未被填充是因爲熊貓根據索引進行數據對齊。當分配df.ix["a"]與另一個數據幀時,它會填充索引匹配的值。爲了說明這一點:

>>> df = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 
>>> df2 = pd.DataFrame(zeros((1, 2)), columns=["x", "y"], index=range(2,3)) 
>>> df 
      x   y 
0 -0.995116 0.132438 
1 -0.023010 -0.211612 
2 -0.053206 0.427369 
>>> df2 
    x y 
2 0 0 
>>> df.ix[:] = df2 
>>> df 
    x y 
0 NaN NaN 
1 NaN NaN 
2 0 0 

在分配numpy的陣列(或列表,...),沒有指數匹配,所以它只是填充數據幀(也播出在這種情況下):

>>> df.ix[:] = df2.values 
>>> df 
    x y 
0 0 0 
1 0 0 
2 0 0 

所以,你的情況,當你嘗試分配df_adf.ix['a'],指數不匹配(多指標與正常指數),並沒有被分配(或更精確:充滿NaN的)。但是,當你第一次轉換df_a也有同樣多指標,它的工作:

>>> df_a = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 
>>> df_b = pd.DataFrame(randn(3, 2), columns=["x", "y"], index=range(3)) 
>>> 
>>> tuples = list(itertools.product(["a", "b"], range(3))) 
>>> df = pd.DataFrame(columns=["x", "y"], index=pd.MultiIndex.from_tuples(tuples)) 
>>> 
>>> df_a.index = pd.MultiIndex.from_tuples([tuple(('a', i)) for i in df_a.index]) 
>>> 
>>> df.ix["a"] = df_a 
>>> df 
      x   y 
a 0 1.533881 1.276075 
    1 -0.5143746 -0.3400633 
    2 -1.071509 1.831282 
b 0  NaN  NaN 
    1  NaN  NaN 
    2  NaN  NaN 

或如上所述,使用numpy的數組時(在.values屬性返回的數據作爲numpy的陣列),但它也行:

>>> df.ix["b"] = df_b.values 
>>> df 
       x   y 
a 0  1.533881 1.276075 
    1 -0.5143746 -0.3400633 
    2 -1.071509 1.831282 
b 0 0.06535034 -0.6276186 
    1 0.008100781 0.9512881 
    2 0.08688541 -0.7101486 

但我認爲,另一種方式來實現這一目標,而不是填充數據幀df,是多索引添加到原數組,然後連接它們

要將其轉化爲多指標,你可以做這樣的:

>>> df_a['df'] = 'a' 
>>> df_b['df'] = 'b' 
>>> 
>>> df_a = df_a.set_index('df', append=True) 
>>> df_b = df_b.set_index('df', append=True) 

或像這樣:

>>> df_a.index = pd.MultiIndex.from_tuples([tuple(('a', i)) for i in df_a.index]) 
>>> df_b.index = pd.MultiIndex.from_tuples([tuple(('b', i)) for i in df_b.index]) 

,然後你可以將它們連接起來:

>>> df = pd.concat([df_a, df_b]) 
>>> df 
      x   y 
    df      
0 a -0.225156 -0.846229 
1 a 1.566139 0.892763 
2 a -1.291920 -0.517408 
0 b 1.464853 0.792709 
1 b -1.307375 -0.360373 
2 b 0.467406 1.249325 
>>> 
>>> df.swaplevel(0,1) 
      x   y 
df      
a 0 -0.225156 -0.846229 
    1 1.566139 0.892763 
    2 -1.291920 -0.517408 
b 0 1.464853 0.792709 
    1 -1.307375 -0.360373 
    2 0.467406 1.249325