【问题标题】:Show pandas Dataframe in webpage and dynamically filter using Dash在网页中显示熊猫数据框并使用 Dash 动态过滤
【发布时间】:2020-02-18 04:07:42
【问题描述】:

我正在尝试使用 Dash 显示数据框。我拥有的数据框是https://www.kaggle.com/timoboz/superbowl-history-1967-2020。我的目标是通过一个搜索按钮在网页上显示数据框,该按钮可以动态搜索所有列并过滤数据框。

到目前为止,我有以下显示数据框的代码。

import pandas as pd
import dash
import dash_table
from dash.dependencies import Input, Output
df  = pd.read_csv('./Data/superbowl.csv')
PAGE_SIZE = 10
app = dash.Dash(__name__)

app.layout = dash_table.DataTable(
    id='datatable-paging',
    columns=[
        {"name": i, "id": i} for i in df.columns #sorted(df.columns)
    ],
    page_current=0,
    page_size=PAGE_SIZE,
    page_action='custom',

    sort_action='custom',
    sort_mode='single',
    sort_by=[]
)


@app.callback(
    Output('datatable-paging', 'data'),
    [Input('datatable-paging', "page_current"),
     Input('datatable-paging', "page_size"),
     Input('datatable-paging', 'sort_by')])
def update_table(page_current,page_size,sort_by):
    if len(sort_by):
        dff = df.sort_values(
            sort_by[0]['column_id'],
            ascending=sort_by[0]['direction'] == 'asc',
            inplace=False
        )
    else:
        # No sort is applied
        dff = df

    return dff.iloc[
           page_current * page_size:(page_current + 1) * page_size
           ].to_dict('records')



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

在阅读了https://dash.plot.ly/datatable/callbacks 文档,尤其是“带有过滤的后端分页”之后,我找不到像单个文本框一样搜索所有列并过滤匹配条目的数据框的方法。

【问题讨论】:

  • 尝试在dash_table.DataTable中添加filter_action='native'作为参数
  • @sumshyftw 每列添加过滤。我正在尝试将所有过滤器合并到一个文本框/输入框,该文本框/输入框过滤所有列。
  • filter_action native 不是服务器端排序 AFAIK

标签: python-3.x pandas plotly plotly-dash


【解决方案1】:

最好的方法是为您的搜索查询使用输入组件。然后可以通过执行 pandas 过滤器来更新表。这将返回任何单元格包含文本的所有行。

下面的过滤器回调示例:

@app.callback(
    Output('datatable', 'data'),
    [Input('filter-input', 'value')])
def update_table(filter_string):
    dff = df[df.apply(lambda row: row.str.contains(filter_string, regex=False).any(), axis=1)]
    return dff.to_dict('records')

您的输入组件在下面(注意使用 debounce - 这意味着只有当用户按下回车时才会执行回调):

import dash_core_components as dcc

dcc.Input(value='', id='filter-input', placeholder='Filter', debounce=True)

将您当前的代码放在一起:

import pandas as pd
import dash
import dash_table
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

df = pd.read_csv('./Data/superbowl.csv')
PAGE_SIZE = 10
app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Input(value='', id='filter-input', placeholder='Filter', debounce=True),
    dash_table.DataTable(
        id='datatable-paging',
        columns=[
            {"name": i, "id": i} for i in df.columns  # sorted(df.columns)
        ],
        page_current=0,
        page_size=PAGE_SIZE,
        page_action='custom',

        sort_action='custom',
        sort_mode='single',
        sort_by=[]
    )
])


@app.callback(
    Output('datatable-paging', 'data'),
    [Input('datatable-paging', 'page_current'),
     Input('datatable-paging', 'page_size'),
     Input('datatable-paging', 'sort_by'),
     Input('filter-input', 'value')])
def update_table(page_current, page_size, sort_by, filter_string):
    # Filter
    dff = df[df.apply(lambda row: row.str.contains(filter_string, regex=False).any(), axis=1)]
    # Sort if necessary
    if len(sort_by):
        dff = dff.sort_values(
            sort_by[0]['column_id'],
            ascending=sort_by[0]['direction'] == 'asc',
            inplace=False
        )

    return dff.iloc[
           page_current * page_size:(page_current + 1) * page_size
           ].to_dict('records')


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

希望这会有所帮助,

奥莉

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2019-04-13
    • 2015-05-28
    相关资源
    最近更新 更多