【问题标题】:Pandas Error: Index contains duplicate entries, cannot reshapePandas 错误:索引包含重复条目,无法重塑
【发布时间】:2021-10-07 15:56:25
【问题描述】:

我的问题似乎重复,因为我发现不同的问题具有相同的错误,如下所示:

Pandas: grouping a column on a value and creating new column headings

Python/Pandas - ValueError: Index contains duplicate entries, cannot reshape

Pandas pivot produces "ValueError: Index contains duplicate entries, cannot reshape

我尝试了这些帖子中提供的所有解决方案,但都没有奏效。我相信这个错误可能是由我的数据集格式引起的,它有字符串而不是数字,并且可能是重复的整数。以下是我的数据集的示例:

protocol_no activity description
1586212 walk twice a day
1586212 drive 5 km
1586212 drive At least 30 min
1586212 sleep NaN
1586212 eat 1500 calories
2547852 walk NaN
2547852 drive NaN
2547852 eat 3200 calories
2547852 eat Avoid pasta
2547852 sleep At least 10 hours

我想要实现的输出是:

protocol_no walk drive sleep eat
1586212 twice a day 5km NaN 1500 calories
2547852 NaN NaN 3200 calories At least 10 hours

我尝试通过如下代码使用 pivot 和 pivot_table:

df.pivot(index="protocol_no", columns="activity", values="description")

但我仍然收到此错误:

ValueError: Index contains duplicate entries, cannot reshape

不知道出了什么问题,所以任何帮助都会有所帮助!

编辑:

我注意到我的数据包含重复的整体,如错误以及@DYZ 和@SeaBean 用户所述。所以我编辑了数据库示例并为我的数据集提供了正确的答案。希望它可以帮助某人。

【问题讨论】:

  • 我对提供的数据执行了您的数据透视语句,但没有收到任何错误消息。您是否在实验中使用了相同的数据?
  • 并非如此。我的数据是严格保密的,所以我不能分享它。我提供了一个类似的例子,但正如你所说,这还不够。

标签: python pandas


【解决方案1】:

如果在使用.pivot() 时遇到重复索引错误,请尝试将.piviot_table()aggfunc='first'(或类似的东西)一起使用

df.pivot_table(index="protocol_no", columns="activity", values="description", aggfunc='first')

当您设置为index 的列具有重复值时,这是一种常见情况。使用aggfunc='first'(或有时aggfunc='sum',视情况而定)很可能可以解决问题。

结果:

activity    drive            eat              sleep         walk
protocol_no                                                     
1586212      5 km  1500 calories                NaN  twice a day
2547852       NaN  3200 calories  At least 10 hours          NaN

编辑

根据您最近编辑的重复条目,您可以通过更改上面的aggfunc 函数来修改上面的解决方案,如下所示:

df.pivot_table(index="protocol_no", columns="activity", values="description", aggfunc=lambda x: ' '.join(x.dropna()))

在这里,我们将aggfunc'first' 更改为lambda x: ' '.join(x.dropna())。它无需添加多行代码即可实现与您想要的输出相同的结果。

结果:

activity                    drive                        eat              sleep         walk
protocol_no                                                                                 
1586212      5 km At least 30 min              1500 calories                     twice a day
2547852                            3200 calories Avoid pasta  At least 10 hours             

【讨论】:

  • 您的解决方案对我的数据有效。您能否详细解释一下“第一”对聚合的作用?
  • @GuilhermeNoronha 对,这是意料之中的。大多数时候first 在这种情况下效果很好。这里的first 作为聚合函数与GroupBy.first(pandas.pydata.org/pandas-docs/stable/reference/api/…) 函数有些相同,有时我们也可以将pivot_tablegroupby() 函数互换使用。在这里,first 是在组中有多个(重复)值的情况下获取组中的第一个。
  • @GuilhermeNoronha 这里的组是protocol_noactivitydescription 组合。如果您有针对特定protocol_noactivity 的描述,那么它将获得唯一的description。 (这是最常见的用例)。如果您对一个 protocol_noactivity 组合有多个描述,它将采用第一个描述。由于这种情况比较少见,first 很可能会得到我们想要的结果。
  • @GuilhermeNoronha 见我上面的编辑。这是将.pivot_table()aggfunc 结合使用的强大功能。它可以实现很多你想要的特性/功能。试试新代码,让我知道你是怎么想的。 :-)
  • 当然,我学会了!并且还从您的解决方案中学到了更多... :)
【解决方案2】:

虽然 SeaBean 的答案适用于我的数据,但我查看了我的数据并注意到它确实包含重复的整体(如我稍后编辑的问题中的示例)。为了解决这个问题,最好的解决方案是对那些重复的条目进行连接。

1- 在加入之前,我需要删除我的数据集的 NaN。否则会引发另一个错误:

df["description"].fillna("", inplace=True)

2- 然后我执行了 grouby 函数加入重复的条目:

df = df.groupby(["protocol_no", "activity"], as_index=False).agg({"description": " ".join})

3- 最后但并非最不重要的一点是,我按照我在问题中的意图执行了枢轴:

df.pivot(index="protocol_no", columns="activity", values="description")

4- 瞧,结果:

protocol_no drive eat sleep walk
1586212 5 km At least 30 min 1500 calories twice a day
2547852 3200 calories Avoid pasta At least 10 hours

5- 我的数据集信息使用df.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 1586212 to 2547852
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   drive   2 non-null      object
 1   eat     2 non-null      object
 2   sleep   2 non-null      object
 3   walk    2 non-null      object
dtypes: object(4)
memory usage: 80.0+ bytes   

感谢 SeaBean 和 DYZ 的见解,希望它能帮助到很多人。 :)

【讨论】:

  • 查看我上面的编辑以获得更简单的解决方案:-)
猜你喜欢
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2015-04-23
  • 2018-05-31
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多