关于索引重复输入的Pandas转向警告

Tar*_*ula 43 python pandas

关于Pandas pivot方法的文档,我们有:

Examples
--------
>>> df
    foo   bar  baz
0   one   A    1.
1   one   B    2.
2   one   C    3.
3   two   A    4.
4   two   B    5.
5   two   C    6.

>>> df.pivot('foo', 'bar', 'baz')
     A   B   C
one  1   2   3
two  4   5   6
Run Code Online (Sandbox Code Playgroud)

DataFrame的结构如下:

   name   id     x
----------------------
0  john   1      0
1  john   2      0
2  mike   1      1
3  mike   2      0
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西:

      1    2   # (this is the id as columns)
----------------------
mike  0    0   # (and this is the 'x' as values)
john  1    0
Run Code Online (Sandbox Code Playgroud)

但是,当我运行该pivot方法时,它说:

*** ReshapeError: Index contains duplicate entries, cannot reshape
Run Code Online (Sandbox Code Playgroud)

这是没有意义的,即使在示例中foo列上有重复的条目.我正在使用name列作为pivot的索引,这是pivot方法调用的第一个参数.

Ali*_*n S 84

据我所知,对pandas的更新,你必须使用pivot_table()而不是pivot().

pandas.pivot_table(df,values='count',index='site_id',columns='week')
Run Code Online (Sandbox Code Playgroud)

  • 有什么不同? (7认同)
  • 我在此[** Q&A **](/sf/ask/3300688401/)中提供了一些详细的示例和替代方法 (2认同)

小智 27

试试这个,

#drop_duplicates removes entries which have same values for 'foo' and 'bar'
df = df.drop_duplicates(['foo','bar'])
df.pivot('foo','bar','baz')
Run Code Online (Sandbox Code Playgroud)

  • 我想对于大多数来这里的人来说,这可能是正确的答案.人们感到困惑,因为他们认为大熊猫要求一个独特的指数.实际上,pandas要求索引和列*一起唯一*即原始帧中没有行**index和列列重复. (7认同)

Wes*_*ney 5

对我有用吗?您可以发布您正在使用的确切枢轴方法调用吗?

In [4]: df.pivot('name', 'id', 'x')
Out[4]: 
id    1  2
name      
john  0  0
mike  1  0
Run Code Online (Sandbox Code Playgroud)

  • 我仍然有 python 3 的这个问题。 (5认同)
  • 我有很多数据,这是一个小功能示例,我会尝试使用原始数据,但错误消息本身就是无意义的,因为索引可以有重复的条目,你怎么看? (3认同)

Rad*_*adu 5

正如几个答案所指出的,问题不在于您的索引中有重复的值(错误消息在这里当然没有帮助),而是您的(index, column). 一些答案建议您删除这些重复项,但我会小心这样做 - 根据我的经验,这很少是正确的选择。通常,您可能希望以某种方式聚合数据,然后进行透视。

我从这篇博文中提取了一些示例和引用,我建议您阅读下面的内容以了解更多详细信息。

给定这样的数据:

df = pd.DataFrame([
    ['a', 'x', 1],
    ['a', 'x', 2],
    ['b', 'x', 3],
    ['b', 'y', 4]
], columns=['g1', 'g2', 'value'])
Run Code Online (Sandbox Code Playgroud)

打印如下:

>>> print(df)
  g1 g2  value
0  a  x      1
1  a  x      2
2  b  x      3
3  b  y      4
Run Code Online (Sandbox Code Playgroud)

ValueError当尝试使用g1索引和g2列进行透视时,我们得到 a :

>>> df.pivot(index='g1', columns='g2', values='value')
...
ValueError: Index contains duplicate entries, cannot reshape
Run Code Online (Sandbox Code Playgroud)

g1请注意,第 0 行和第 1 行的和g2:具有相同的值(a, x)。因此,当 pandas 创建数据透视表时,对于a索引、g1列,如何选择一个值:1 或 2?答案是……我们不能!这就是为什么删除重复项有效,但它可能不是您想要的,因为您正在丢失潜在有用的数据。那么我们能做什么呢?

解决方案 1:聚合

并不总是有一个对您的用例有意义的聚合函数,但如果有的话,有多种方法可以实现这一点。

>>> print(df)
  g1 g2  value
0  a  x      1
1  a  x      2
2  b  x      3
3  b  y      4
Run Code Online (Sandbox Code Playgroud)
>>> df.pivot(index='g1', columns='g2', values='value')
...
ValueError: Index contains duplicate entries, cannot reshape
Run Code Online (Sandbox Code Playgroud)
df.pivot_table(index='g1', columns='g2', values='value', aggfunc='sum')
Run Code Online (Sandbox Code Playgroud)

所有这些都会产生相同的结果:

g2    x    y
g1          
a   3.0  NaN
b   3.0  4.0
Run Code Online (Sandbox Code Playgroud)

但如果您不需要这笔钱怎么办?也许逗号分隔值对您的情况有用?

df_agg = df.groupby(by=['g1', 'g2']).value.sum().reset_index()
df_agg.pivot(index='g1', columns='g2', values='value')
Run Code Online (Sandbox Code Playgroud)

要得到:

g2    x    y
g1          
a   1,2  NaN
b     3    4
Run Code Online (Sandbox Code Playgroud)

或者您可以用作list您的aggfunc

pv = df.pivot_table(index='g1', columns='g2', values='value', aggfunc=list)
Run Code Online (Sandbox Code Playgroud)

然后我们就可以爆炸了!

>>> pv.explode('x').explode('y')
g2  x    y
g1        
a   1  NaN
a   2  NaN
b   3    4
Run Code Online (Sandbox Code Playgroud)

解决方案 2:给自己另一把钥匙

这是基于这个答案

>>> 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
Run Code Online (Sandbox Code Playgroud)

现在我们可以使用复合索引进行透视:

>>> 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
Run Code Online (Sandbox Code Playgroud)

这与上面的分解示例几乎相同,只是稍有set_index('g1')不同。

希望这可以帮助!我经常遇到这个问题并且通常会忘记所有这些..