Панды заполняют 0 для несуществующих категорий в value_counts () - PullRequest
1 голос
/ 01 октября 2019

проблема : я группирую результаты в моем DataFrame, смотрю на value_counts(normalize=True) и пытаюсь отобразить результат на графике.

Проблема в том, что график должен содержать частоты,В некоторых группах некоторые значения не встречаются. В этом случае соответствующий value_count не равен 0, он не существует. Для столбца это значение 0 не учитывается, а результирующий столбец слишком большой.

пример : вот минимальный пример, иллюстрирующий проблему: допустим, DataFrame содержитнаблюдения за экспериментами. Когда вы выполняете такой эксперимент, серия наблюдений собирается. Результатом эксперимента являются относительные частоты наблюдений, собранных для него.

df = pd.DataFrame()

df["id"] = [1]*3 + [2]*3 + [3]*3
df["experiment"] = ["a"]*6 + ["b"] * 3
df["observation"] = ["positive"]*3 + ["positive"]*2 + ["negative"]*1 + ["positive"]*2 + ["negative"]*1

dataframe

  • Есть два типа эксперимента ". a "и" b "
  • наблюдения, которые относятся к одной и той же оценке эксперимента, получают один и тот же идентификатор.

Итак, здесь эксперимент a был проведен 2 раза, эксперимент bтолько один раз.

Мне нужно сгруппировать по идентификатору и эксперименту, а затем усреднить результат.

plot_frame = pd.DataFrame(df.groupby(["id", "experiment"])["observation"].value_counts(normalize=True))
plot_frame = plot_frame.rename(columns={"observation":"percentage"})

plot_frame

На рисункевыше, вы уже можете увидеть проблему. Оценка с идентификатором 1 видела только положительные наблюдения. Относительная частота «минус» должна быть 0. Вместо этого она не существует. Если я построю это, соответствующий столбик окажется слишком высоким, синие столбцы должны добавить до одного:

sns.barplot(data=plot_frame.reset_index(), 
            x="observation", 
            hue="experiment", 
            y="percentage")

plt.show()

barplot

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Вы можете добавить строки, заполненные 0, используя метод unstack / stack с аргументом fill_value=0. Попробуйте это:

df.groupby(["id", "experiment"])["observation"].value_counts(normalize=True).unstack(fill_value=0).stack()
0 голосов
/ 01 октября 2019

Я нашел хакерское решение, итерируя по индексу и вручную заполняя пропущенные значения:

for a,b,_ in plot_frame.index:
    if (a,b,"negative") not in plot_frame.index:
        plot_frame.loc[(a,b,"negative"), "percentage"] = 0

Теперь получим желаемый график:

barplot

Мне не особенно нравится это решение, поскольку оно очень специфично для моего индекса и, вероятно, плохо масштабируется, если категории становятся более сложными

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...