Plotly.Express + Pandas 多级列索引

3

我对Pandas和Plotly相对较新。我将用一个MWE直接提出我的问题,说明我想要做什么:

import pandas
import plotly.express as px

df = pandas.DataFrame(
    {
        'n': [1,1,1,1,2,2,2,3,3,3,4,4],
        'x': [0,0,0,0,1,1,1,2,2,2,3,3],
        'y': [1,2,1,1,2,3,3,3,4,3,4,5],
    }
)

mean_df = df.groupby(by=['n']).agg(['mean','std'])

fig = px.scatter(
    mean_df,
    x = ('x','mean'),
    y = ('y','mean'),
    error_y = ('y','std'),
)
fig.show()

这段代码没有达到我的预期。 mean_df 数据框如下所示:

     x              y          
  mean  std      mean       std
n                              
1    0  0.0  1.250000  0.500000
2    1  0.0  2.666667  0.577350
3    2  0.0  3.333333  0.577350
4    3  0.0  4.500000  0.707107

我希望使用plotly.express绘制x_meany_mean的图表,并在y轴上添加误差线。但是,当数据框中存在子列时,我不确定该如何操作... 经过一些研究,我发现代码mean_df.columns = [' '.join(col).strip() for col in mean_df.columns.values]可以将前面的数据框转换为...
   x mean  x std    y mean     y std
n                                   
1       0    0.0  1.250000  0.500000
2       1    0.0  2.666667  0.577350
3       2    0.0  3.333333  0.577350
4       3    0.0  4.500000  0.707107

所以现在我只需要执行以下操作:
fig = px.scatter(
    mean_df,
    x = 'x mean',
    y = 'y mean',
    error_y = 'y std',
)

为了获得所需的结果。然而,尽管这样做正是我想要做的,但感觉并不是正确的方法...

1个回答

3
与您的研究类似,需要展平多级列。您可以使用索引切片。这确实不会改变mean_df
以下是更多更新。 Plotly Express 旨在设计为简单的 API。将数据框架简化/结构化以适合 x、y、color、hover_name 等 概念作为字符串地址的列是典型用例。如果正在使用多级索引列,则可以传递 seriesarray。下面演示了两种变体。
import pandas
import plotly.express as px

df = pandas.DataFrame(
    {
        'n': [1,1,1,1,2,2,2,3,3,3,4,4],
        'x': [0,0,0,0,1,1,1,2,2,2,3,3],
        'y': [1,2,1,1,2,3,3,3,4,3,4,5],
    }
)

mean_df = df.groupby(by=['n']).agg(['mean','std'])

fig = px.scatter(
    mean_df.loc[:,pd.IndexSlice[:,"mean"]].droplevel(1,1),
    x = "x",
    y = "y",
)
fig

使用多个一级键

fig = px.scatter(
    mean_df.loc[:,pd.IndexSlice[:,"mean"]].droplevel(1,1),
    x = "x",
    y = "y",
    error_y = mean_df.loc[:,("y","std")].values
)
fig.show()
px.scatter(
    x = mean_df.loc[:,("x","mean")],
    y = mean_df.loc[:,("y","mean")],
    error_y = mean_df.loc[:,("y","std")]
)

谢谢您的答复。我会点赞,因为它解决了我在问题中提出的需求。但是,我正在寻找一种不会删除列的解决方案,因为我也想要绘制标准值。我会更新我的问题来反映这一点,抱歉。 - user171780
已更新以涵盖您的问题修改。在我看来,保持简单是很好的,因此如果有无法通过字符串引用的列,请传递一个系列或数组。 - Rob Raymond

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接