【问题标题】:Python: boxplot dataframe with multi-indexPython:具有多索引的箱线图数据框
【发布时间】:2022-01-03 01:02:31
【问题描述】:

我正在尝试创建一个箱线图,在 x 轴上我将引用数据框的两列,而在 y 轴上我将显示第三列的值。

让我参考一个示例数据框:

  Lvl1  Lvl2  value
0    A     1      1
1    A     2      2
2    A     1      3
3    B     2      4
4    B     1      5
5    B     2      6

现在,我想绘制对应于 Lvl1 和 Lvl2 的组的箱线图。例如,对于由 (Lvl1 = A, Lvl2 = 1) 表示的组,箱线图将计算 {1,3} 的值。

我知道我可以创建一个像 Lvl0 这样的新列,它类似于 Lvl1 + Lvl2,但是有没有办法在没有这种操作的情况下创建箱线图?

关于以下代码:

import pandas as pd
import matplotlib.pyplot as plt

dataset = pd.DataFrame(
    {'Lvl1': ['A', 'A', 'A', 'B', 'B', 'B'], 'Lvl2': [1, 2, 1, 2, 1, 2], 'value': [1, 2, 3, 4, 5, 6]})
grouped = dataset.groupby(['Lvl1', 'Lvl2'])
grouped.boxplot()
plt.show()

我收到一个错误:
KeyError:“[Index(['A', 1], dtype='object')] 中没有一个在 [index] 中”

提前谢谢你!

【问题讨论】:

    标签: python pandas plot boxplot multi-index


    【解决方案1】:

    尝试使用 seaborn 以获得更简单的解决方案。我想它在这里得到了回答:Grouping boxplots in seaborn when input is a DataFrame

    使用您的数据:

    import seaborn as sns
    import pandas as pd
    
    data = pd.DataFrame({'lvl1': ['A', 'A', 'A', 'B', 'B', 'B'], 
                         'lvl2': [1, 2, 1, 2, 1, 2], 
                         'value': [1, 2, 3, 4, 5, 6]})
    
    df_long = pd.melt(data, "lvl1", var_name="lvl2", value_name="result")
    
    sns.boxplot(x="lvl1", hue="lvl2", y="result", data=df_long)
    

    我们得到:

    如果您需要更多关卡,请尝试将绘图与 sns.FacetGrid (https://seaborn.pydata.org/generated/seaborn.FacetGrid.html) 结合使用。 这里我建议使用 sns.catplot:

    data = pd.DataFrame({'lvl1': ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B'], 
                     'group': ['1', '2', '1', '2', '1', '2', '2', '1'], 
                     'has_something': [True, False, False, True, True, False, True, False], 
                     'before': [3, 4, 5, 5, 3, 4, 2, 6],
                     'after': [1, 2, 3, 4, 5, 6, 2, 3], 
                     'baseline': [1, 0, 0, 1, 1, 0, 0, 1]})
    
    df = pd.melt(data, ["lvl1", 'group', 'has_something'], value_name="result")
    
    sns.catplot(data=df, x='lvl1', y='result',
    col='group', kind='box', hue='variable', col_wrap=2, margin_titles=True)
    

    结果在这里:

    为了在图中包含“has_something”变量,您可以使用 FacetGrid 或通过“has_something”分隔数据,并使用不同的过滤数据制作两个图。

    【讨论】:

    • 谢谢。如果有超过 2 个级别,我该如何扩展它?我不知道melt在这里能对我们有什么帮助。
    • 我在答案中添加了有关更多级别的部分。希望它会有所帮助。
    【解决方案2】:

    您可以通过 seaborn 做到这一点。以下代码适用于您的数据:

    import pandas as pd
    import seaborn as sns
    
    dataset = pd.DataFrame(
        {
            'Lvl1': ['A', 'A', 'A', 'B', 'B', 'B'], 'Lvl2': [1, 2, 1, 2, 1, 2], 
            'value': [1, 2, 3, 4, 5, 6]
        }
    )
    ax = sns.boxplot(x='Lvl1', y='value', hue="Lvl2", data=dataset)
    

    过期输出:

    【讨论】:

    • 谢谢。对于我们考虑超过 2 列的情况,是否有扩展?比如让我们说 3 个级别或更多?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2015-06-06
    • 2018-04-15
    相关资源
    最近更新 更多