绘制调查中的分组信息

时间:2019-03-02 15:01:56

标签: python pandas matplotlib

我有一个数据框,其中包含一个感兴趣的变量(分类,此处为YesNo等)和一个分组变量(请参见下文):

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

由此,我想在条形图中检索并绘制每组的累积数据。

详细信息:对于组AYesNo等的百分比,对于组别相同。 命令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中),并且不确定这是否是数据转换或可视化的问题。

This的问题是在询问类似问题,但我无法使其与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 :(得分:2)

您应该在不选择unstack的情况下执行columnsgroupby的输出为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

答案 1 :(得分:1)

我认为更好的方法是使用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)

您的解决方案is mainly syntactic sugar for the alternative and much more verbose,显然是在需要处理列之前使用的,例如需要列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)

编辑:

要缩放,请使用Series.value_counts中的normalize=True

.value_counts(normalize=True)