【问题标题】:How to make a monthly boxplot for each group in a data frame in python如何在python的数据框中为每个组制作每月箱线图
【发布时间】:2020-06-11 20:36:44
【问题描述】:

我有一些这样的数据:

    Export Country  Import Terminal  Arrival Date  Value
     Country            Port A         1/15     135138
     Country            Port A         1/15     153232
     Country            Port A         3/15     116116
        .                  .             .           .
        .                  .             .           .
        .                  .             .           .
        .                  .             .           .
     Country            Port B         1/15     155462
     Country            Port B         2/15     116532
     Country            Port B         1/16     456321
     Country            Port B         2/16     865313
        .                  .             .           .
        .                  .             .           .
        .                  .             .           .
        .                  .             .           .

我使用了 df = df.groupby(['Import Terminal', 'Arrival Date'])[Value].sum() 并以:

Import Terminal   Arrival    Sum of Value 
    Port A         1/15        288370
                   3/15        116116
                     .            .
                     .            .
    Port B         1/15        155462
                     .            .
                     .            .

现在我需要浏览每个进口终端,并使用“到达月份”和“价值总和”列为每个进口终端制作月度箱线图。我该怎么做,我迷路了。

【问题讨论】:

    标签: python pandas boxplot


    【解决方案1】:

    虚拟数据示例:

    import pandas as pd
    
    df = pd.DataFrame({'Export Country': np.random.randint(0,10,1000),
        'Import Terminal': np.random.randint(0,3,1000),
        'Arrival Date': np.random.randint(0,10,1000),
        'Value':np.random.randint(0,10,1000),})
    
    gb = df.groupby(['Import Terminal', 'Arrival Date'])['Value'].sum().reset_index()
    gb['month'] = gb['Arrival Date'].apply(lambda x: int(x.split('/')[0]))
    for terminal, group in gb.groupby('Import Terminal'):
        group.boxplot(by='month', column='Value')
        plt.suptitle('Import terminal {}'.format(terminal))
        plt.title('')
    

    【讨论】:

    • 这比我目前得到的更接近,但我正在尝试为每个导入终端绘制一个箱形图,其中一个框显示每个月的值。
    【解决方案2】:

    Pandas 提供了 DataFrame 的箱线图功能,请参阅此处的文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.boxplot.html

    您可以像这样在您的案例中创建一个箱线图:

    df.reset_index().boxplot(by=['Arrival Date']
    

    另一种(更详细和明确的)方法是直接在 matplotlib 中构造箱线图。

    为什么要重置索引?
    您提供的结果(可能)是具有 MultiIndex 索引的系列(单列数据框),因此没有箱线图方法(奇怪,对吗?)。您可以通过 reset_index 或强制转换为 DataFrame df2 = pd.DataFrame(df) 或使用 groupby 的 as_index=False 参数将其设为 DataFrame

    部分数据的图如下所示

    每个箱组将汇总每个到达数据(即来自 A 和 B,或所有进口终端)的所有观测值的“值总和”响应变量值。大概您希望单独获取每个终端数据,因为您需要“通过每个终端”。 如果您需要对数据进行切片并为每个终端创建一个单独的箱线图(值按月分组在框中),那么我的建议是通过 terminals=df2['Import Terminal'].unique() 获取终端列表并遍历终端列表子集数据框(暗示 df_subs = df[ df['Import Terminal'] == value] ) 并为每个子集创建上面的箱线图。

    请注意,pandas 在箱线图的底层使用 matplotlib,并且 matplotlib 必须安装在您的环境中。

    如果您可以提供错误消息和您可用/想要使用的 python 包,那么也许我可以提供进一步的帮助。例如,您可以使用比 pandas 更好地包装图的其他包(例如 seaborn,参见 catplots https://seaborn.pydata.org/tutorial/categorical.html

    import seaborn as sns
    sns.catplot(x="Arrival Date", y="Value", hue="Import Terminal", kind="box", data=df2)
    

    不清楚到达日期的格式是什么,如果您需要根据它们计算月份,如果这是“月/年”,那么您只需要针对 X 轴对它们进行适当的排序。

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-10-30
      • 1970-01-01
      • 2016-10-24
      • 2021-11-12
      • 2022-06-27
      • 2021-05-21
      相关资源
      最近更新 更多