【问题标题】:How to reshape a Pandas data frame before passing to a Plotly function?如何在传递给 Plotly 函数之前重塑 Pandas 数据框?
【发布时间】:2020-10-03 15:33:59
【问题描述】:

我正在尝试使用Plotly 中的Table() 函数创建一个数据表。

我的数据如下:

import pandas as pd

test_df = pd.DataFrame({'Manufacturer':['Mercedes', 'Buick', 'Ford', 'Buick', 'Buick', 'Ford', 'Buick', 'Chrysler', 'Ford', 'Buick', 'Chrysler', 'Ford', 'Buick', 'Ford', 'Ford', 'Chrysler', 'Chrysler', 'Ford', 'Chrysler', 'Chrysler', 'Chrysler', 'Buick'],
                          'Metric':['MPG', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score', 'Score'],
                          'Statistic':['External', 'Min', 'Max', 'Average', 'Median', '90th', '95th', '99th', 'Min', 'Max', 'Average', 'Median', '90th', '95th', '99th','Min', 'Max', 'Average', 'Median', '90th', '95th', '99th'],
                          'Value':[22, 3.405, 100.29, 4.62, 4.425, 5.34, 5.83, 7.75, 2.6323, 210, 4.193, 3.28, 5.04, 6.36, 11.01, 3.72, 43, 4.98, 4.82, 5.775, 6.18, 7.182],
                       })

我希望能够创建一个如下所示的表:

Manufacturer    Min      Max      Average      Median      90th      95th      99th
Buick           3.405    210      4.62         4.425       5.04      5.83      7.182
Chrysler        3.72     43       4.193        4.82        5.775     6.18      7.75
Ford            2.6323   100.29   4.98         3.28        5.34      6.36      11.01

执行此操作的代码如下所示(硬编码时):

import plotly.graph_objects as go 
go.Figure(go.Table(
        header=dict(
            values=["Manufacturer", "Min", "Max",
                    "Average", "Median", "90th",
                    "95th", "99th"],
            font=dict(size=10),
            align="left"
        ),
        cells=dict(
            values=[['Buick', 'Ford', 'Chrysler'],    # Headers (could change based on the source file)
                    [3.405, 3.72, 2.6323],            # Min values
                    [210, 43, 100.29],                # Max values
                    [4.62, 4.193, 4.98],              # Average values
                    [4.425, 4.82, 3.28],              # Median values
                    [5.04, 5.775, 5.34],              # 90th percentile values
                    [5.83, 6.18, 6.36],               # 95th percentile values
                    [7.182, 7.75, 11.01]              # 99th percentile values
                   ],
            align = "left")                                     
))

根据https://plotly.com/python/table/ 的文档,cells 参数需要一个列表列表,并且可以采用 Pandas 数据框(太棒了!)。

使用文档中的示例,传递 Pandas 数据框的代码如下所示:

# THIS IS THE EXAMPLE FROM THE DOCS (SHOWING THE USE OF A DATA FRAME)
fig = go.Figure(data=[go.Table(
    header=dict(values=list(df.columns),
                fill_color='paleturquoise',
                align='left'),
    cells=dict(values=[df.Rank, df.State, df.Postal, df.Population],
               fill_color='lavender',
               align='left'))
])

我最勇敢的尝试失败了:

仅按“分数”记录过滤:

test_df_subset = test_df[(test_df['Metric'] == 'Score') & (test_df['Manufacturer'].isin(['Buick', 'Ford', 'Chrysler']))]

创建数据透视表:

temp_df = pd.pivot_table(data=test_df_subset,index=['Statistic', 'Manufacturer']) 

拆开数据透视表:

temp_df.unstack(0)

问题:我将如何重塑我的test_df 数据框以便能够将其传递给go.Figure() 函数中的data 和cells 参数?

提前致谢!

【问题讨论】:

  • 您是否尝试将header 中的values 参数替换为df.columns.to_list(),并将cells 中的values 参数替换为df.values?

标签: pandas plotly plotly-dash plotly-python


【解决方案1】:

你已经很接近了,这是一种方法

import plotly.graph_objects as go 

cols_ = ["Manufacturer", "Min", "Max",
         "Average", "Median", "90th",
         "95th", "99th"]
manufacturers = ['Buick', 'Ford', 'Chrysler']

#this is what you are looking for
df_ = (test_df[test_df['Manufacturer'].isin(manufacturers)]
              .set_index(['Manufacturer', 'Statistic'])
               ['Value'].unstack()
               .reset_index()[cols_]
               )

go.Figure(go.Table(
        header=dict(
            values=cols_,
            font=dict(size=10),
            align="left"
        ),
        cells=dict(
            values=df_.T, # note the T here
            align = "left")                                     
))

与您的方法相比,我认为 df_(在我的符号中)等同于 temp_df.unstack(0)['Value'].reset_index()[cols_] 与您的符号并使用 cols_ 按预期订购它们

【讨论】:

  • 谢谢你,@Ben.T。您的解决方案可以完美地处理测试和生产数据。
猜你喜欢
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 2012-12-10
  • 2020-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多