сюжет сгруппирован по данным опроса - PullRequest
0 голосов
/ 02 марта 2019

У меня есть фрейм данных с интересующей переменной (категориальный, здесь Yes, No и т. Д.) И группирующей переменной (см. Ниже):

import pandas as pd
import numpy as np
df = pd.DataFrame({ 
    'ID': range(100),
    'group': np.random.choice(['A', 'B', 'C'], 100),
    'Response':np.random.choice(['Yes','No','Other', np.nan], 100)})

Из этого я бынравится извлекать и отображать накопленные данные по группам на гистограмме.

Подробно: для группы A, процент Yes, No и т. д., то же самое для группы по.Команда df['Response'].groupby(df['group']).value_counts() уже дает мне такой вывод:

group  Response
A      Other       14
       No           8
       Yes          8
       nan          8
B      Other       11
       nan         11
       No           5
       Yes          4
C      No           9
       Yes          9
       nan          7
       Other        6
Name: Response, dtype: int64

Это то, что я хочу, но я не могу найти способ построить его соответствующим образом (в matplotlib или seaborn) и не уверен, что этопроблема преобразования или визуализации данных.

Этот вопрос задает о чем-то похожем, но я не могу заставить его работать с unstack:

df = df['group'].unstack(0, fill_value = 0)

AttributeError: у объекта 'RangeIndex' нет атрибута 'remove_unused_levels'

и

df = df['group'].unstack(0, fill_value = 0)
df.index.name = None
df.columns.name = None
df.plot.bar(stacked=True)

только графики ID (без группировки).

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Я думаю, лучше использовать группирование по столбцу в string и получить столбец после groupby для обработки:

df1 = df.groupby('group')['Response'].value_counts().unstack(fill_value=0)

Альтернативой является использование crosstab:

df1 = pd.crosstab(df['group'], df['Response'])

Для удаления имен индексов и столбцов можно использовать ваше решение или DataFrame.rename_axis:

#pandas 0.24+
df1.rename_axis(index=None, columns=None).plot.bar(stacked=True)

#pandas bellow
#df1.rename_axis(None).rename_axis(None, axis=1).plot.bar(stacked=True)

Ваше решение является в основном синтаксическим сахаром дляальтернативный и гораздо более многословный , очевидно, использует, если нужно, столбец обработки прежде, например, нужно нижний регистр столбца Response:

df1 = df['Response'].str.lower().groupby(df['group']).value_counts().unstack(fill_value=0)

Первое решение возможно, но нужно 2 строки:

df['Response'] = df['Response'].str.lower()
df1 = df.groupby('group')['Response'].value_counts().unstack(fill_value=0)

РЕДАКТИРОВАТЬ:

Для масштабирования используйте normalize=True in Series.value_counts:

.value_counts(normalize=True)
0 голосов
/ 02 марта 2019

Вы должны сделать unstack без выбора columns, вывод groupby равен Series, и обратите внимание, что вы используете Series groupby, а не pd.DataFrame.groupby

df['Response'].groupby(df['group']).value_counts().unstack(fill_value=0)

type(df['Response'].groupby(df['group']).value_counts())
Out[207]: pandas.core.series.Series
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...