如何为 python 中数据框中的每个组制作月度箱线图

How to make a monthly boxplot for each group in a data frame in python

我有一些这样的数据:

    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
                     .            .
                     .            .

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

带有虚拟数据的示例:

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('')

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

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

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

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

为什么 reset_index?
您提供的结果(可能)是一个带有 MultiIndex 索引的系列(单列数据框),因此没有箱线图方法(奇怪,对吧?)。您可以通过 reset_index 或通过转换为 DataFrame df2 = pd.DataFrame(df) 或使用 groupby

as_index=False 参数使其成为 DataFrame

部分数据的图表如下所示

每个框组将总结每个到达数据(即来自 A 和 B,或所有进口终端)的所有观测值的 'Sum of Value' 响应变量值。大概您希望单独获取每个终端数据,因为您需要“通过每个终端”。 如果您需要对数据进行切片并为每个终端创建一个单独的箱形图(值按月分组在框中)那么我的建议是通过 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)

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