【问题标题】:Multilevel dataframe to dash table多级数据框到破折号表
【发布时间】:2021-10-20 08:36:06
【问题描述】:

拥有这个数据框:

显示为 dashtable 的最佳方式是什么? 我试过手动操作列,但没有用

bottom_col_row = df2.columns.get_level_values(1)  #------------
df2.columns = df2.columns.droplevel(1)             #------------
columns=[{'name': [x[0], x[1]], 'id': x[0]} for x in zip(df2.columns, bottom_col_row)]

【问题讨论】:

    标签: python pandas dataframe plotly-dash


    【解决方案1】:

    好吧,这有点棘手,但这是让它在 Dash 的 dash_table 开源表库中工作的一种方法:

    import dash
    import numpy as np
    import pandas as pd
    
    from dash import dash_table
    
    # Create a pd.MultiIndex from the combination of t & m:
    t = ["1M", "3M", "6M", "1Y"]
    m = ["IV", "RV", "Spread"]
    
    arrays = np.array(sorted([[b, a] for a in m for b in t]))
    
    df = pd.DataFrame(
        sorted(arrays, key=lambda x: (x[0][1], x[0][0])), columns=["Tenor", None]
    )
    
    index = pd.MultiIndex.from_frame(df)
    
    # Create a mock df using random np floats, specifying the columns
    # with the previously created pd.MultiIndex and the "index" here
    # as the row labels
    df2 = pd.DataFrame(
        np.around(np.random.randn(3, 12), decimals=2),
        index=["EURUSD", "GBPUSD", "USDJPY"],
        columns=index,
    )
    
    # Dash app
    app = dash.Dash(__name__)
    
    """For getting the columns fed correctly to dash_table,
    a two-row multi-header can be created by supplying 
    the 'name' key of `DataTable.columns` with an array.
    
    The trick then is to create unique IDs, which requires 
    manipulation of the data into a list of dictionaries 
    where each cell value's key is the artificially created
    concatenated string (I just combined them; e.g., "1M_IV" 
    is one of the unique keys, and so on).
    
    Note: the use of '**' is a useful Python3+ way to merge 
    dicts during list/dict comprehensions. This is necessary
    for including the true index 'Ccy Pair' as key,value 
    pairs in addition to a dict comprehension through the data.
    Thus I needed to also transpose the df..."""
     
    app.layout = dash_table.DataTable(
        id="table",
        columns=[{"name": ["Tenor", "Ccy Pair"], "id": "Ccy Pair"}]
        + [{"name": [x1, x2], "id": f"{x1}_{x2}"} for x1, x2 in df2.columns],
        data=[
            {
                **{"Ccy Pair": df2.index[n]},
                **{f"{x1}_{x2}": y for (x1, x2), y in data},
            }
            for (n, data) in [
                *enumerate([list(x.items()) for x in df2.T.to_dict().values()])
            ]
        ],
        merge_duplicate_headers=True,   # ← here's the main ? ? 
        # Optional interactivity parameters*:
        editable=True,
        filter_action="native",
        sort_action="native",
        sort_mode="multi",
        column_selectable="single",
        row_selectable="multi",
        row_deletable=True,
        selected_columns=[],
        selected_rows=[],
        page_action="native",
        page_current= 0,
        page_size= 10,
    )
    
    if __name__ == "__main__":
        app.run_server(debug=True, dev_tools_hot_reload=True)
    
    

    结果:

    并添加了编辑功能*:

    基本上,这是对我了解如何操作正确的数据结构最有帮助的资源: https://dash.plotly.com/datatable/style

    每个单元格(每行;即,给表的 data 参数的字典数组中的每个字典)都有一个 唯一 列 ID,即 f"{x1}_{x2}" 其中 x1 ∈ ['1M', '3M', '6M', '1Y']和 x2 ∈ ['IV', 'RV', 'Spread']

    【讨论】:

    • 这行得通,但本机仪表板功能(排序、过滤...等)会丢失。
    • true,在这种情况下需要明确添加这些道具。看起来很棒,非常感谢
    • @Crovish 实际上,不!我已经更新了答案,以显示所有其他 dash_table 功能如何保持保留并根据需要提供?非常整洁,您当然可以根据需要确定样式等。您也知道
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多