Plotly Dash:如何显示通过文件上传创建的Pandas数据中的计算值?

问题描述 投票:0回答:1

我在Pandas数据帧中具有以下数据:

     df = pd.DataFrame({'Make':['Mercedes', 'BMW', 'Mercedes', 'Mercedes', 'Chrysler', 'Chrysler', 'Chrysler', 'Chrysler', 'BMW', 'Chrysler', 'BMW', 'Mercedes', 'BMW', 'Mercedes'],
                          'Dimension':['Styling', 'Styling', 'Price', 'Styling', 'MPG', 'MPG', 'Styling', 'Styling', 'MPG', 'MPG', 'Price', 'Price', 'Styling', 'MPG'],
                          'Country':['USA', 'USA', 'USA', 'Germany', 'USA', 'USA', 'USA', 'England', 'Germany', 'USA', 'Germany', 'Poland', 'Italy', 'USA'],
                          'LowValue':['64', '61', '70', '65', '59', '68', '63', '57', '58', '55', '69', '63', '69', '61'],
                          'HighValue':['82', '95', '93', '95', '87', '93', '85', '85', '95', '92', '83', '87', '80', '80']})

我正在使用Plotly Dash框架构建Web应用程序。该应用程序允许用户上传文件并在屏幕上呈现内容。我想显示一些有关上载文件时创建的Pandas数据框的摘要统计信息。

这是上传文件并呈现应用的代码:

import base64
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import dash_table
import datetime
from datetime import datetime as dt
import io
import os
import pandas as pd
import re


# initialize the application
app = dash.Dash()

# define the layout of the app
app.layout = html.Div([

    html.Div([
        dcc.Upload(
            id='upload-data',
            children=html.Div([
                'Drag and Drop or ',
                html.A('Select Files')
            ]),
            style={
            'width' : '50%',
            'height' : '60px',
            'lineHeight' : '60px',
            'borderWidth' : '1px',
            'borderStyle' : 'dashed',
            'borderRadius' : '5px',
            'textAlign' : 'center',
            'marginTop' : '10px',
            'marginRight' : '10px',
            'marginBottom' : '50px',
            'marginLeft' : '300px',
            'color' : '#87ceeb'
            },
            multiple=True
            ),
        html.Div(id='output-data-upload'),
        ]),

])


def parse_contents(contents, filename, date):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # assume that the user uploaded a CSV file
            df = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # assume that the user uploaded an Excel file
            df = pd.read_excel(io.BytesIO(decoded))
        elif 'txt' or 'tsv' in filename:
            # assume that the user uploaded a TXT file
            df = pd.read_csv(io.StringIO(decoded.decode('utf-8')), delimiter = r'\s+')
    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
            ])

    # transform the original data frame to get the average of low value for Styling
    df_new = df[(df['Dimension'] == 'Styling')]
    df_new['LowValue'] = pd.to_numeric(df_new['LowValue'])
    mean_of_low_value = df_new['LowValue'].mean()

    return html.Div([
        html.H5(filename),
        html.H6(datetime.datetime.fromtimestamp(date)),

        dash_table.DataTable(
            id='table',
            columns=[{'name': i, 'id': i} for i in df.columns],
            data=df.to_dict('records'),
            sort_action='native',
            filter_action='native',
            page_size= 5,
            style_table={'height' : '300px',
                         'overflowY' : 'auto'},
            style_cell={'width' : '300px',
                        'height' : '30px',
                        'textAlign' : 'left'}
            ),

])



@app.callback(Output('output-data-upload', 'children'),
    [Input('upload-data', 'contents')],
    [State('upload-data', 'filename'),
     State('upload-data', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
        children = [
            parse_contents(c, n, d) for c, n, d in
            zip(list_of_contents, list_of_names, list_of_dates)]
        return children


if __name__ == '__main__':
    app.run_server(debug = True, use_reloader=True)

A df对象在文件上传时创建。然后,我操纵df以获得LowStyling分数的平均值。

使用此数据集,mean_of_low_value variable为63.1666。

问题:如何在屏幕上显示以下内容?

“平均样式得分为:63.1666”

提前感谢!

python pandas plotly plotly-dash
1个回答
0
投票

您可以创建一个新组件(例如html.Div()html.H1()html.P()等),然后在children属性中同时包含转换为字符串的文本和数值,例如

html.Div(children=['The average Styling score is: ' + str(mean_of_low_value)]),

或者如果您想四舍五入(假设为两位数),则为您

html.Div(children=['The average (rounded) Styling score is: ' + format(mean_of_low_value, '.2f')]

我更新了您的代码(在下面复制),以包括上述两个示例。

import base64
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import dash_table
import datetime
from datetime import datetime as dt
import io
import os
import pandas as pd
import re

# initialize the application
app = dash.Dash()

# define the layout of the app
app.layout = html.Div([

    html.Div([
        dcc.Upload(
            id='upload-data',
            children=html.Div([
                'Drag and Drop or ',
                html.A('Select Files')
            ]),
            style={
            'width' : '50%',
            'height' : '60px',
            'lineHeight' : '60px',
            'borderWidth' : '1px',
            'borderStyle' : 'dashed',
            'borderRadius' : '5px',
            'textAlign' : 'center',
            'marginTop' : '10px',
            'marginRight' : '10px',
            'marginBottom' : '50px',
            'marginLeft' : '300px',
            'color' : '#87ceeb'
            },
            multiple=True
            ),
        html.Div(id='output-data-upload'),
        ]),

])


def parse_contents(contents, filename, date):

    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # assume that the user uploaded a CSV file
            df = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # assume that the user uploaded an Excel file
            df = pd.read_excel(io.BytesIO(decoded))
        elif 'txt' or 'tsv' in filename:
            # assume that the user uploaded a TXT file
            df = pd.read_csv(io.StringIO(decoded.decode('utf-8')), delimiter = r'\s+')
    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
            ])

    # transform the original data frame to get the average of low value for Styling
    df_new = df[(df['Dimension'] == 'Styling')]
    df_new['LowValue'] = pd.to_numeric(df_new['LowValue'])
    mean_of_low_value = df_new['LowValue'].mean()

    return html.Div([

        html.H5(filename),
        html.H6(datetime.datetime.fromtimestamp(date)),

        dash_table.DataTable(
            id='table',
            columns=[{'name': i, 'id': i} for i in df.columns],
            data=df.to_dict('records'),
            sort_action='native',
            filter_action='native',
            page_size= 5,
            style_table={'height' : '300px',
                         'overflowY' : 'auto'},
            style_cell={'width' : '300px',
                        'height' : '30px',
                        'textAlign' : 'left'}
            ),

        html.Div(children=['The average Styling score is: ' + str(mean_of_low_value)]),

        html.Div(children=['The average (rounded) Styling score is: ' + format(mean_of_low_value, '.2f')]),

])


@app.callback(Output('output-data-upload', 'children'),
    [Input('upload-data', 'contents')],
    [State('upload-data', 'filename'),
     State('upload-data', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
        children = [
            parse_contents(c, n, d) for c, n, d in
            zip(list_of_contents, list_of_names, list_of_dates)]
        return children


if __name__ == '__main__':
    app.run_server(debug = True, use_reloader=True)
© www.soinside.com 2019 - 2024. All rights reserved.