Выравнивание ячеек гистограммы Pandas

#python #pandas #dataframe #histogram

#python #pandas #фрейм данных #гистограмма

Вопрос:

У меня есть фрейм данных, который выглядит следующим образом:

 train_data_10users = pd.DataFrame({'target':['A','A','B', 'B', 'C'], 'day_of_week':[4,2,4,4,1]})

 target  day_of_week
0   A            4
1   A            2
2   B            4
3   B            4
4   C            1
 

и я хочу иметь гистограмму подсчетов по day_of_week для каждой цели, т.е.

 "A" should have:
0,1,3,5,6:0
2,4:1
"B" should have
0,1,2,3,5,6:0
4:2
"C" should have 1:1, the rest:0
 

Вот сводная таблица, которая показывает реальные данные, которые я хочу видеть на гистограммах (примечание: fillna):

 pivot = pd.pivot_table(train_data_10users,
                       index=["target"], columns=["day_of_week"], aggfunc='size', fill_value=0)

day_of_week 0   1   2   3   4   5   6
target                          
Ashley  390 328 1078    293 115 0   0
Avril   148 402 273 318 87  104 311
Bill    308 239 105 24  54  7   65
Bob 51  285 72  284 330 0   0
 

Несмотря на то, что в groupby может отсутствовать несколько дней, добавление правильных xticks делает свое дело:

 from matplotlib import pyplot as plt
import pandas as pd

fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10))
for idx, (user, sub_df) in enumerate(
        pd.groupby(train_data_10users[["target", "day_of_week"]], 'target')): 
    ax = axes[idx // 4, idx % 4]
    sub_df.hist(ax=ax, label=user, color=color_dic.get(user), bins=7)
    ax.set_xticks(range(7))
    ax.legend()
 

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

Upd.Вот как это выглядит в соответствии с принятым ответом:

 fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10), sharey=True)
...
sub_df.hist(ax=ax, label=user, color=color_dic.get(user), bins=range(8))
ax.set_xticks(range(8))
ax.set_xticks(np.arange(8) 0.5)
ax.set_xticklabels(range(7))
 

hist_result

Комментарии:

1. Что такое train_data_10users ? Что такое axes ?

2. Это мои оси фрейма данных и подзаголовка

3. Для тех, кто пытается воссоздать фрейм данных: train_data_10users = pd.DataFrame({'target':['A','A','B', 'B', 'C'], 'day_of_week':[4,2,4,4,1]})

4. Итак, что вы ожидаете, удалите те, у которых есть ноль / NaN, из hist bin? На самом деле это не гистограмма.

5. Посмотрите мой отредактированный ответ, если он соответствует вашим потребностям.

Ответ №1:

Попробуйте:

 fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10))
for idx, (user, sub_df) in enumerate(
    pd.groupby(train_data_10users[["target", "day_of_week"]], 'target')): 
    ax = axes[idx // 4, idx % 4]

    # note bin is forced to range(7)
    sub_df.hist(ax=ax, label=user, bins=range(7))

    # offset the xticks
    ax.set_xticks(np.arange(7)   .5)

    # name the label accordingly
    ax.set_xticklabels(range(7))
 

Вывод с bins=range(7) :
введите описание изображения здесь

Комментарии:

1. Обратите внимание, что я также меняю bins на range(7) . Это немного отличается от bins=7 bins=7 деления диапазона min-max на 7 ячеек, в то время как формальный набор специально для (0,1,2,3,4,5,6)

2. Да, я заметил это и удалил свой предыдущий комментарий. Однако все еще есть небольшая проблема. Теперь hist немного смещен вправо и не отображает значение для первого дня. Позвольте мне опубликовать картинку как Upd.

3. измените смещение на ` 0.5`.

4. Я пытался, но он просто делает обратное, с 0.5 он не будет показывать значения за последний день..

5. Нашел проблему, измените bins=range(8) . Кроме того, подумайте о том, чтобы поместить sharey=True subplots .