正如几个答案所指出的,问题不在于您的索引中有重复的值(错误消息在这里肯定没有帮助),而是您有重复的 (index, column)。一些答案建议您只删除这些重复项,但我会小心这样做 - 根据我的经验,这很少是正确的选择。通常,您可能希望以某种方式聚合您的数据,然后然后进行数据透视。
我从this blog post 中提取了一些示例和引用,我建议您阅读下面的详细信息。
给定这样的数据:
df = pd.DataFrame([
['a', 'x', 1],
['a', 'x', 2],
['b', 'x', 3],
['b', 'y', 4]
], columns=['g1', 'g2', 'value'])
这样打印:
>>> print(df)
g1 g2 value
0 a x 1
1 a x 2
2 b x 3
3 b y 4
当尝试以g1 作为索引并以g2 作为列进行旋转时,我们得到一个ValueError:
>>> df.pivot(index='g1', columns='g2', values='value')
...
ValueError: Index contains duplicate entries, cannot reshape
请注意,第 0 行和第 1 行具有相同的 g1 和 g2 值:(a, x)。因此,当 pandas 创建您的旋转数据框时,对于 a 索引、g1 列,如何只选择一个值:1 或 2?答案是……我们不能!这就是删除重复项有效的原因,但它可能不是您想要的,因为您正在丢失可能有用的数据。那么我们能做些什么呢?
解决方案 1:聚合
对于您的用例并不总是有一个聚合函数,但如果有的话,有几种方法可以实现这一点。
df.pivot_table(index='g1', columns='g2', values='value', aggfunc='sum')
df_agg = df.groupby(by=['g1', 'g2']).value.sum().reset_index()
df_agg.pivot(index='g1', columns='g2', values='value')
df.groupby(by=['g1', 'g2']).value.sum().unstack()
所有这些都会产生相同的结果:
g2 x y
g1
a 3.0 NaN
b 3.0 4.0
但是如果您不需要总和怎么办?也许逗号分隔值对您有用?
df.pivot_table(
index='g1',
columns='g2',
values='value',
aggfunc=lambda x: ','.join(x.astype('str'))
)
# we need to convert to strings before we can join
得到:
g2 x y
g1
a 1,2 NaN
b 3 4
或者您可以使用list 作为您的aggfunc:
pv = df.pivot_table(index='g1', columns='g2', values='value', aggfunc=list)
然后我们就可以爆炸了!
>>> pv.explode('x').explode('y')
g2 x y
g1
a 1 NaN
a 2 NaN
b 3 4
解决方案 2:给自己另一把钥匙
这是基于this answer
>>> df['key'] = df.groupby(['g1', 'g2']).cumcount()
>>> df
g1 g2 value key
0 a x 1 0
1 a x 2 1
2 b x 3 0
3 b y 4 0
现在我们可以使用复合索引进行旋转:
>>> df.pivot(index=['key', 'g1'], columns='g2', values='value').reset_index().drop(columns='key')
g2 g1 x y
0 a 1.0 NaN
1 b 3.0 4.0
2 a 2.0 NaN
这与上面分解的示例几乎相同,只是一个set_index('g1')。
希望这会有所帮助!我经常遇到这个问题,通常会忘记这一切..