考虑数据框d1
和d2
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
但是,当我执行groupby
和sum
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
任何人都可以解释出现了什么问题吗?
答案 0 :(得分: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'])
具体而言,在具有相同索引的数据帧(具有键的规范的非multiIndex)的串联中,创建的新MultiIndex
获得与原始标签无关的标签0,...,len(d)
。 (如果查看索引,您会看到每个标签具有不同ID的多个副本)。
具体来说,这是由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)
。
答案 1 :(得分:1)
从keys
移除concat()
参数将允许您所需的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()
)