熊猫为value_counts()

时间:2019-10-01 09:35:06

标签: python pandas seaborn

问题:我正在将结果分组到我的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”
  • 属于同一实验评估的
  • 观测值具有相同的ID。

因此,在这里,实验a已完成2次,实验b仅进行了一次。

我需要按ID分组并进行实验,然后取平均结果。

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

plot_frame

在上图中,您已经可以看到问题。 id为1的评估仅看到了积极的观察结果。 “负”的相对频率应为0。相反,它不存在。如果我将其绘制出来,则对应的条形太高,蓝色条形应合计为一个:

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

plt.show()

barplot

2 个答案:

答案 0 :(得分:1)

您可以使用带有参数unstack的{​​{1}} / stack方法添加用0填充的行。试试这个:

fill_value=0

答案 1 :(得分:0)

通过遍历索引并手动填写缺失值,我发现了一个有问题的解决方案:

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

我不太喜欢这种解决方案,因为它非常适合我的索引,并且如果类别变得更加复杂,可能无法很好地扩展