web-dev-qa-db-fra.com

Python Dash: chargement pandas dataframes dans la table de données)

J'ai essayé de créer une application avec Dash récemment, mais malgré la lecture des nombreux guides, je ne peux tout simplement pas comprendre comment importer une trame de données pandas dans les données de Dash) table (qui est essentiellement un pandas dataframe, sauf hébergé sur le web et réactif).

La plupart des exemples illustrent comment sélectionner manuellement certaines colonnes/lignes à partir d'une trame de données qui est déjà codée en dur dans l'exemple, comme dans ici . Cependant, dans ma situation, le dataframe est construit dans mon code (et pandas est le moyen le plus simple de le faire), donc je dois trouver un moyen de convertir un pd.Dataframe() en dash_table.DataTable().

Comment puis-je faire fonctionner cela? En utilisant les références, j'ai essayé le code suivant pour envoyer un dict de ma trame de données à dash_table.DataTable(), mais rien ne s'affiche.

Mon code:

## Imports
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table

from dash.dependencies import Input, Output, State

import datetime as dt
import pandas as pd
import numpy as np

## Custom functions that creates the pandas dataframe
from Twitter_functions import old_tweets

app = dash.Dash(dev_tools_hot_reload=True)
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True


app.layout = html.Div(children=[

    html.H3('Twitter App'),

    dcc.Input('ScreenName_Input', type='text'),

    html.Button(id='screenNames_submit_button', children='Submit'),

    dash_table.DataTable(id='Tweet_table')

])

@app.callback(
    Output(component_id='Tweet_table', component_property='data'),
    [Input(component_id='screenNames_submit_button', component_property='n_clicks_timestamp')],
    [State(component_id='ScreenName_Input', component_property='value')]
)
def display_tweets(submit_button, screen_names):
    tweets = old_tweets(screen_names)

    return tweets.to_dict(orient='records')

if __name__ == '__main__':
    app.run_server(debug=True)
3
Coolio2654

Après quelqu'un m'a également répondu sur les forums de complot (heureusement), il semble que la réponse finale soit de prédéfinir son tableau de données avec les colonnes du pandas dataframe qui va y entrer à un moment donné, comme ça,

dash_table.DataTable(
    id='table',
    columns=[
    {'name': 'Column 1', 'id': 'column1'},
    {'name': 'Column 2', 'id': 'column2'},
    {'name': 'Column 3', 'id': 'column3'},
    {'name': 'Column 4', 'id': 'column4'},
    {'name': 'Column 5', 'id': 'column5'}]
)

, puis envoyez un dict de votre pandas dataframe.

8
Coolio2654

C'est un peu long et non testé, mais basé sur https://community.plot.ly/t/dash-datatable-using-callbacks/6756 , il semble que Dash DataTables nécessite implicitement un valeur initiale si vous souhaitez les modifier via un rappel.

Essayez de changer cette ligne:

dash_table.DataTable(id='Tweet_table')

Pour ça:

dash_table.DataTable(id='Tweet_table', rows=[{}])
2
Peter Leimbigler

Voici une autre solution qui a fonctionné pour moi:

     dt_col_param = []

     for col in output_df.columns:
            dt_col_param.append({"name": str(col), "id": str(col)})

    dash_table.DataTable(
            columns=dt_col_param,
            data=output_df.to_dict('records')
        )

Mon plus gros problème était que mon application continuait de lever une exception sur tout ce que j'essayais de passer dans l'argument 'colonnes' pour dash_table.DataTable (...).

J'espère que cela vous aidera à ne rien coder en dur.

2
Jamie

En supposant que votre fonction de tweets renvoie une trame de données, l'ajout de colonnes de table en tant que deuxième sortie à votre rappel devrait fonctionner.

@app.callback(
    [Output(component_id='Tweet_table', component_property='data'),
     Output(component_id='Tweet_table', component_property='columns')
    [Input(component_id='screenNames_submit_button', component_property='n_clicks_timestamp')],
    [State(component_id='ScreenName_Input', component_property='value')]
)
def display_tweets(submit_button, screen_names):
    tweets = old_tweets(screen_names)
    columns = [{'name': col, 'id': col} for col in tweets.columns]
    data = tweets.to_dict(orient='records')
    return data, columns
1
haydard