代码之家  ›  专栏  ›  技术社区  ›  JAG2024

使用groupby和pandas数据框中的多列从字符串数据创建条形图

  •  5
  • JAG2024  · 技术社区  · 7 年前

    我想在python中用“是”或“否”的数据计数来绘制一个包含多个X类别的条形图。我已经开始编写一些代码,但我相信我的工作进展缓慢,无法找到我想要的解决方案。我可以选择使用Seaborn、Matplotlib或Pandas的解决方案,但 not Bokeh,因为我想使出版物质量数字达到这个比例。

    最终我想要的是:

    • X轴上有“独木舟”、“巡航”、“皮艇”和“船舶”类别的条形图
    • 按“颜色”分组,因此绿色或红色
    • 显示“是”响应的比例:所以“是”行的数量除以“红色”和“绿色”的计数,在本例中,这是4个红色和4个绿色,但这可能会改变。

    以下是我正在使用的数据集:

    导入熊猫为pd 数据=['ship':'是','独木舟':'是','巡航':'是','皮艇':'否','颜色''红色'125;,'船舶':'是','巡航':'是','皮艇''''','独木舟'''否','颜色''绿色','船舶':'是''''''''''''''''船舶':'是'''''''''''''''''''是'''''''''''''''''''''''''''''''''''''''''''''''''''''''','ship':'yes'、'cruise':'是“,”皮划艇“:”是“,”皮划艇“:”否“,”颜色“:”红色“,”船舶“:”否“,”巡航“:”是“,”皮划艇“:”否“,”皮划艇“:”是“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”红色“” df=pd.数据帧(数据) < /代码>

    这就是我刚开始说的:

    print(df['color'].value_counts())
    
    红色=4必须有更好的方法来编码,而不是手动。也许使用len()?
    绿色= 4
    
    #获取每种类型的计数
    ca=df[独木舟]。数值_计数())
    cr=df[巡航]。数值_计数())
    kA=df[‘kayak’]。值_counts())
    sh=df[‘ship’]。值_counts())
    打印(CA、CR、KA、SH)
    
    #按颜色分组
    CAC=df.groupby([“独木舟”,“颜色”])
    crc=df.groupby([“巡航”,“颜色”])
    kac=df.groupby(['kayak','color'])
    shc=df.groupby([“发货”,“颜色”])
    
    作图
    cac2=cac['color'].值_counts().unstack())
    cac2.plot(kind='bar',title='canoane by color')
    < /代码> 
    
    

    但我真正想要的是所有的x类都在一个图上,只显示“是”响应的结果,并将其作为“是”的比例,而不仅仅是计数。帮助?< P / P我正在缓慢地找到我想要的解决方案。我可以使用一种解决方案,它要么是海生的,要么是matplotlib,要么是熊猫,但是因为我想把出版质量的数字按比例放大。

    最终我想要的是:

    • X轴上有“独木舟”、“巡航”、“皮艇”和“船舶”类别的条形图
    • 按“颜色”分组,因此绿色或红色
    • 显示“是”响应的比例:所以“是”行数除以“红色”和“绿色”的计数,在本例中是4个红色和4个绿色,但这可能会改变。

    以下是我正在使用的数据集:

    import pandas as pd
    data = [{'ship': 'Yes','canoe': 'Yes', 'cruise': 'Yes', 'kayak': 'No','color': 'Red'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'Yes','canoe': 'No','color': 'Green'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'No','canoe': 'No','color': 'Green'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'No','canoe': 'No','color': 'Red'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'Yes','canoe': 'No','color': 'Red'},{'ship': 'No', 'cruise': 'Yes', 'kayak': 'No','canoe': 'Yes','color': 'Green'},{'ship': 'No', 'cruise': 'No', 'kayak': 'No','canoe': 'No','color': 'Green'},{'ship': 'No', 'cruise': 'No', 'kayak': 'No','canoe': 'No','color': 'Red'}]
    df = pd.DataFrame(data)
    

    这就是我从以下几点开始:

    print(df['color'].value_counts())
    
    red = 4 # there must be a better way to code this rather than manually. Perhaps using len()?
    green = 4
    
    # get count per type
    ca = df['canoe'].value_counts()
    cr = df['cruise'].value_counts()
    ka = df['kayak'].value_counts()
    sh = df['ship'].value_counts()
    print(ca, cr, ka, sh)
    
    # group by color
    cac = df.groupby(['canoe','color'])
    crc = df.groupby(['cruise','color'])
    kac = df.groupby(['kayak','color'])
    shc = df.groupby(['ship','color'])
    
    # make plots 
    cac2 = cac['color'].value_counts().unstack()
    cac2.plot(kind='bar', title = 'Canoe by color')
    

    enter image description here

    但我真正想要的是所有的x类都在一个图上,只显示“是”响应的结果,并将其作为“是”的比例,而不仅仅是计数。帮助?

    3 回复  |  直到 7 年前
        1
  •  1
  •   Scott Boston    7 年前

    让我们试试。

    导入熊猫为pd 将numpy导入为np 将matplotlib.pyplot导入为plt 从ITertools导入GroupBy 数据=['ship':'是','独木舟':'是','巡航':'是','皮艇':'否','颜色''红色'125;,'船舶':'是','巡航':'是','皮艇''''','独木舟'''否','颜色''绿色','船舶':'是''''''''''''''''船舶':'是'''''''''''''''''''是'''''''''''''''''''''''''''''''''''''''''''''''''''''''','ship':'yes'、'cruise':'是“,”皮划艇“:”是“,”皮划艇“:”否“,”颜色“:”红色“,”船舶“:”否“,”巡航“:”是“,”皮划艇“:”否“,”皮划艇“:”是“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”红色“” df=pd.数据帧(数据) df1=df.replace([“yes”,“no”],[1,0]).groupby(“color”).mean().stack().rename(“%yes”).to_frame()) 定义添加线(ax、xpos、ypos): line=plt.line2d([xpos,xpos],[ypos+.1,ypos], transform=ax.transaxs,color='gray') line.set_clip_on(假) ax.添加线条(线条) def label_len(我的_index,级别): labels=my_index.get_level_值(level) 返回[(k,sum(1代表i in g))代表k,g代表groupby(labels)] def label_group_bar_table(ax,df): YPOS=- 1 比例=1./df.index.size 对于范围内的级别(df.index.nlevels)[::-1]: POS=0 对于label,label-len(df.index,level)中的rpo: Lxpos=(pos+.5*rpos)*比例 ax.text(lxpos,ypos,label,ha='center',transform=ax.transaxs) 添加线条(ax、pos*比例、ypos) POS=RPOS 添加线条(ax、pos*比例、ypos) YPOS==1 颜色列表=['绿色','红色'] cp=sns.color_调色板(颜色列表) ax=sns.barplot(x=df1.index,y=“%yes”,hue=df1.index.get_-level_-values(0),data=df1,palete=cp) #2行以下删除默认标签 ax.set xtickLabels('') ax.set xlabel('') 标签组栏表(ax,df1) < /代码>

    输出:

    输出:

    enter image description here

        2
  •  2
  •   ImportanceOfBeingErnest    7 年前

    不完全确定我是否正确理解这个问题。看起来,查看每艘船类型的答案比例会更有意义。 and color.

    导入matplotlib.pyplot as plt 将熊猫作为PD导入 数据=['ship':'是','独木舟':'是','巡航':'是','皮艇':'否','颜色''红色'125;,'船舶':'是','巡航':'是','皮艇''''','独木舟'''否','颜色''绿色','船舶':'是''''''''''''''''船舶':'是'''''''''''''''''''是'''''''''''''''''''''''''''''''''''''''''''''''''''''''','ship':'yes'、'cruise':'是“,”皮划艇“:”是“,”皮划艇“:”否“,”颜色“:”红色“,”船舶“:”否“,”巡航“:”是“,”皮划艇“:”否“,”皮划艇“:”是“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”绿色“,”船舶“:”否“,”巡航“:”否“,”皮划艇“:”否“,”皮划艇“:”否“,”颜色“:”红色“” df=pd.数据帧(数据) ax=df.replace([“yes”,“no”],[1,0]).groupby(“color”).mean().transmose().plot.bar(color=[“g”,“r”]) ax.set_title('比例“是”根据船型和颜色回答') 显示() < /代码>

    这意味着,例如,25%的绿色独木舟回答“是”。

    钕颜色。

    import matplotlib.pyplot as plt
    import pandas as pd
    data = [{'ship': 'Yes','canoe': 'Yes', 'cruise': 'Yes', 'kayak': 'No','color': 'Red'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'Yes','canoe': 'No','color': 'Green'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'No','canoe': 'No','color': 'Green'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'No','canoe': 'No','color': 'Red'},{'ship': 'Yes', 'cruise': 'Yes', 'kayak': 'Yes','canoe': 'No','color': 'Red'},{'ship': 'No', 'cruise': 'Yes', 'kayak': 'No','canoe': 'Yes','color': 'Green'},{'ship': 'No', 'cruise': 'No', 'kayak': 'No','canoe': 'No','color': 'Green'},{'ship': 'No', 'cruise': 'No', 'kayak': 'No','canoe': 'No','color': 'Red'}]
    df = pd.DataFrame(data)
    
    ax = df.replace(["Yes","No"],[1,0]).groupby("color").mean().transpose().plot.bar(color=["g","r"])
    ax.set_title('Proportion "Yes" answers per of boat type and color')
    plt.show()
    

    enter image description here

    这意味着,例如,25%的绿色独木舟回答“是”。

        3
  •  0
  •   DataPsycho    7 年前

    不确定您是否正在寻找它,请告诉我它是否有效。

    导入熊猫为pd 将Seaborn导入为sns 将matplotlib.pyplot导入为plt 整齐的熔接(df,id_vars=['color'],var_name='variable',value_name='value') total_df=tidy_df[['variable'].groupby('variable').size().reset_index()) tidy_df=tidy_df.groupby(['color'、'variable'、'value']).size().reset_index()) 合并后的“df=pd.merge”(整齐的“df,total”df,on='variable',how='left',后缀=“'u left”,“'u right”)) 合并后的“df”[“proportion”]=合并后的“df”[“0_left”]/合并后的“df”[“0_right”] #合并后的“df”[合并后的“df”[“value”]=“yes”] palete=“green”:“green”,“red”:“red”可选您可以选择自己的 plt.图(图尺寸=(12,6)) sns.barplot(x='variable',y='proportion',hue='color',data=merged_f[merged_f['value']='yes'],palete=palete) PLT.Xticks(旋转=65) #plt.savefig('numbers.png') 显示() < /代码>

    enter image description here