How to solve ValueError: Index contains duplicate entries, cannot reshape

How to solve ValueError: Index contains duplicate entries, cannot reshape

我正在尝试拆开 MultiIndex 系列,以便我可以将系列相互绘制。

import pandas as pd
import numpy as np

dicts = {}

index = np.linspace(1, 50)
index[2] = 2.0
index2 = index.copy()
index2[3] = 3.0

for n in range(5):
    if n == 1:
        dicts['test' + str(n)] = pd.Series(np.linspace(0, 20) ** (n / 5),
                                           index=index2)
    else:
        dicts['test' + str(n)] = pd.Series(np.linspace(0, 20) ** (n / 5),
                                           index=index)

s = pd.concat(dicts, names=('test', 'displacement'))
s.unstack(level='test').plot()

最后一行的 unstack() 得到 ValueError: Index contains duplicate entries, cannot reshape。 Whosebug 的其他问题似乎都与数据透视表有关,但我并不是要汇总数据;简单地绘制它。

我希望每个测试有 1 个图和 1 条线(MultiIndex 的 0 级)。每行都是系列值与位移(MultiIndex 的级别 1)。

我目前的技巧是:

for test_name, test in s.groupby(level='test'):
    test.index = test.index.droplevel()
    test.plot()

plt.show()

如有任何帮助,我们将不胜感激。

您可以在DF.set_index中设置append=True,这样就可以避免在unstack操作时重新默认写入条目。它只添加之前未堆叠列中不存在的条目。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")

df = pd.concat(dicts, names=('test', 'displacement')).reset_index()
labels = np.unique(df['test'].values).tolist()
df.set_index(['test', 'displacement'], append=True, inplace=True)
df.unstack(level='test').plot(figsize=(10,10), use_index=False,               
                              legend=False, title="Grouped Plot")
plt.legend(loc='upper left', fontsize=12, frameon=True, labels=labels)
plt.show()


如果您希望所有绘图都从原点开始,您可以使用 array_split 根据唯一标签的总长度将未堆叠的 dataframe 对象拆分为相等大小,即 5 [ Test0Test4]如下:

df = pd.concat(dicts, names=('test', 'displacement')).reset_index()
labels = np.unique(df['test'].values).tolist()
df.set_index(['test', 'displacement'], append=True, inplace=True)

fig, ax = plt.subplots(figsize=(10,10))
for test_sample in range(len(labels)):
    np.array_split(df.unstack('test'), len(labels))[test_sample].plot(grid=True, 
                   use_index=False, ax=ax, legend=False, cmap=plt.cm.get_cmap('jet'))
plt.legend(loc='upper left', fontsize=12, frameon=True, labels=labels)
plt.xlim(0,50)
plt.title("Grouped Plot")
plt.show()