Как решить ValueError: Индекс содержит повторяющиеся записи, не может изменить форму

python pandas matplotlib seaborn

1507 просмотра

1 ответ

Я пытаюсь развернуть серию 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. Все остальные вопросы StackOverflow, похоже, относятся к сводным таблицам, но я не пытаюсь агрегировать данные; просто заговор.

Я хотел бы иметь 1 график с 1 линией для каждого теста (уровень 0 MultiIndex). Каждая строка будет значением Серии в зависимости от смещения (уровень 1 MultiIndex).

Мой хак на данный момент это:

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

plt.show()

Любая помощь приветствуется.

Автор: blokeley Источник Размещён: 08.11.2019 11:11

Ответы (1)


0 плюса

Решение

Вы можете установить append=Trueв DF.set_indexтаким образом , что она позволяет избежать записи в письменной форме по умолчанию снова во время unstackработы. Он добавляет только те записи, которых ранее не было в столбце unstacked.

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()

Изображение1


Если вы хотите, чтобы все графики начинались с начала координат, вы можете использовать, 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()

Image2

Автор: Nickil Maveli Размещён: 21.08.2016 08:41
Вопросы из категории :
32x32