Python 熊猫为值_counts()中不存在的类别填写0

Python 熊猫为值_counts()中不存在的类别填写0,python,pandas,seaborn,Python,Pandas,Seaborn,问题:我正在对数据帧中的结果进行分组,查看值\u计数(normalize=True)并尝试在条形图中绘制结果 问题是条形图应该包含频率。在某些组中,某些值不会出现。在这种情况下,对应的值\u count不是0,它不存在。对于条形图,不考虑该0值,结果条形图太大 示例:下面是一个简单的示例,它说明了问题:假设数据帧包含用于实验的观察值。当你进行这样的实验时,会收集一系列的观察结果。实验结果是为它收集的观测的相对频率 df = pd.DataFrame() df["id"] = [1]*3 + [

问题:我正在对数据帧中的结果进行分组,查看
值\u计数(normalize=True)
并尝试在条形图中绘制结果

问题是条形图应该包含频率。在某些组中,某些值不会出现。在这种情况下,对应的
值\u count
不是0,它不存在。对于条形图,不考虑该0值,结果条形图太大

示例:下面是一个简单的示例,它说明了问题:假设数据帧包含用于实验的观察值。当你进行这样的实验时,会收集一系列的观察结果。实验结果是为它收集的观测的相对频率

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

  • 有两种实验类型,“a”和“b”
  • 属于同一实验评估的观察结果被赋予相同的id
这里,实验a已经做了两次,实验b只做了一次

我需要根据id和实验分组,然后平均结果

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

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

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

plt.show()

我找到了一个黑客解决方案,通过迭代索引并手动填充缺少的值:

for a,b,_ in plot_frame.index:
    if (a,b,"negative") not in plot_frame.index:
        plot_frame.loc[(a,b,"negative"), "percentage"] = 0
现在,这将生成所需的绘图:


我并不特别喜欢这个解决方案,因为它非常特定于我的索引,如果类别变得更复杂,可能无法很好地扩展。您可以使用
unstack
/
stack
方法和参数
fill\u value=0
,添加用0填充的行。试试这个:

df.groupby(["id", "experiment"])["observation"].value_counts(normalize=True).unstack(fill_value=0).stack()