使用Pandas Unstack()遇重复索引错误的原因及解决方法
ValueError: Index contains duplicate entries, cannot reshape 原因及解决方法
示例代码与数据
你使用的示例代码:
import pandas as pd a = {'a': ['ce', 'ce', 'ce', 'ce', 'ce', 'ce'], 'b' : ['SAM', 'SAM', 'SAM', 'WHR', 'SAM', 'WHR'], 'c': ['11-22-2015', '11-23-2015', '11-24-2015', '11-25-2015', '11-26-2015', '11-27-2015'], 'd' : ['ICU', 'ICU', 'ICU', 'MED', 'MED', 'SUR'], 'e' : [1, 2, 4, 6, 5, 3]} df = pd.DataFrame(a)
生成的DataFrame:
| a | b | c | d | e |
|---|---|---|---|---|
| ce | SAM | 11-22-2015 | ICU | 1 |
| ce | SAM | 11-23-2015 | ICU | 2 |
| ce | SAM | 11-24-2015 | ICU | 4 |
| ce | WHR | 11-25-2015 | MED | 6 |
| ce | SAM | 11-26-2015 | MED | 5 |
| ce | WHR | 11-27-2015 | SUR | 3 |
错误原因
执行df.set_index(['d', 'c', 'b']).unstack(['b', 'd'])时报错的核心原因是:
你要unstack的两个级别(b和d)在MultiIndex行索引中不相邻,被中间的c级别隔开。当pandas尝试同时将这两个非相邻级别转换为列MultiIndex时,无法正确重组数据结构,误判存在重复的索引条目,从而抛出该错误。
注:虽然你的行索引本身没有重复条目,但非相邻级别的跨层级unstack会导致内部重组逻辑冲突。
解决方法
方法1:调整行索引顺序,让要unstack的级别相邻
将行索引设置为['c', 'b', 'd'](让b和d相邻,c作为行索引的最外层),再执行unstack:
df_unstacked = df.set_index(['c', 'b', 'd']).unstack(['b', 'd'])
执行后会得到以日期c为行索引,(列名, b, d)为列MultiIndex的宽表。
方法2:分步unstack
先unstack其中一个级别,再unstack另一个,绕过非相邻级别直接unstack的问题:
# 先unstack b,再unstack d df_unstacked = df.set_index(['d', 'c', 'b']).unstack('b').unstack('d')
此方法会得到与方法1完全一致的结果。
方法3:使用pivot(更直观的行列转换)
如果你的目标是将c作为行索引,b和d作为列维度,直接用pivot方法更清晰,也不会触发索引错误:
# 仅转换e列 df_unstacked = df.pivot(index='c', columns=['b', 'd'], values='e') # 同时转换a和e列 df_unstacked = df.pivot(index='c', columns=['b', 'd'], values=['a', 'e'])
内容的提问来源于stack exchange,提问作者SHENOOOO
相关产品推荐
相关产品推荐

