2017-04-18 45 views
2

的水平綜上所述考慮dataframes d1d2爲什麼不GROUPBY上正確指數

d1 = pd.DataFrame(dict(
     A=list('111222'), 
     B=list('xyzxyz'), 
     C=range(6) 
    )) 

d2 = pd.DataFrame(dict(
     A=list('111222'), 
     B=list('xyzxyz'), 
     C=range(6) 
    )) 

我想然而這些串聯並執行groupby

df = pd.concat([d.set_index('A') for d in [d1, d2]], keys=['d1', 'd2']) 
print(df) 

     B C 
    A  
d1 1 x 0 
    1 y 1 
    1 z 2 
    2 x 3 
    2 y 4 
    2 z 5 
d2 1 x 0 
    1 y 1 
    1 z 2 
    2 x 3 
    2 y 4 
    2 z 5 

,當我做了groupbysum

df.groupby(level='A').C.sum() 

A 
1  0 
1  2 
1  4 
2  6 
2  8 
2 10 
Name: C, dtype: int64 

這不是我所期待的。

我可以拆開df並重新拼湊回來在一起,然後進行groupby ...
我預計

pd.DataFrame(
    df.values, 
    pd.MultiIndex.from_tuples(df.index.values, names=df.index.names), 
    df.columns.values 
).groupby(level='A').C.sum() 

A 
1  6 
2 24 
Name: C, dtype: int64 

誰能解釋什麼錯誤?

回答

1

我相信這是一個錯誤。讓您的指數MultiIndex是一個小黑客的作品

df = pd.concat([d.set_index(['A', [np.nan]*len(d))]) for d in [d1, d2]], keys=['d1', 'd2']) 

另一種解決方案是反向的DataFrames

df = pd.concat([d.set_index(['A']) for d in [d1, d2.sort_index(ascending=False)]], 
       keys=['d1', 'd2']) 

一個具體而言,在相同指數dataframes的級聯,其是非多指標與指定密鑰時,創建的新MultiIndex將獲得與原始標籤無關的標籤0,...,len(d)。 (如果您查看索引,您會看到每個標籤有多個不同編號的副本)。

具體而言,它是由於在pandas.core.reshape.concat

def _make_concat_multiindex(indexes, keys, levels=None, names=None): 
    ... 
    ... # Somewhere here we treat the non identical axis 
    ... 
    if isinstance(new_index, MultiIndex): 
     new_levels.extend(new_index.levels) 
     new_labels.extend([np.tile(lab, kpieces) for lab in new_index.labels]) 
    else: 
     new_levels.append(new_index) 
     new_labels.append(np.tile(np.arange(n), kpieces)) 

所以下面的代碼段中,如果索引是不是多指數已經分配標籤是np.arange(n)

+0

我贊同你。我查看了索引,發現等級值是相同的並且重複。在「正常」形成的多指數中,各個級別不會重複,但標籤會是這樣。做得好! – piRSquared

1

去除concat()keys參數可以讓你的期望groupby()成功:

df = pd.concat([d.set_index('A') for d in [d1, d2]]) 
df.groupby(level='A').C.sum() 

另外,如果keys需要留下來,你可以用reset_index()和重複groupby()那裏:

df = pd.concat([d.set_index('A') for d in [d1, d2]], keys=['d1', 'd2']) 
(df.groupby(level='A').sum() 
    .reset_index() 
    .groupby('A').sum() 
) 
+0

我不是在尋找工作。我正在尋找一個解釋。 – piRSquared