You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Pandas DataFrame转换为指定的类别-日期宽表布局?

解决DataFrame行列转换及Flask展示问题

一、Pandas最优转换方案:使用pivot函数

这是最直接高效的方法,无需手动构建字典,Pandas原生支持这类行列转换需求:

代码示例

import pandas as pd

# 模拟原始DataFrame数据
raw_data = {
    "类别": ["Blue", "Red", "Green", "Red", "Blue", "Red", "Green"],
    "日期": ["10/24", "10/25", "10/23", "10/24", "10/23", "10/26", "10/26"],
    "数量": [7, 10, 5, 2, 3, 11, 3],
    "备注": [None] * 7
}
df = pd.DataFrame(raw_data)

# 转换为目标宽格式
wide_df = df.pivot(
    index="类别",  # 作为行标识的列
    columns="日期",  # 需要转为列的字段
    values="数量"  # 填充单元格的数值
).fillna("").reset_index()  # 把NaN替换为空白,将索引转回普通列

# 按目标顺序调整列(可选,确保日期排序符合需求)
wide_df = wide_df[["类别", "10/23", "10/24", "10/25", "10/26"]]

特殊情况处理

如果存在同一类别+同一日期的重复数据,改用pivot_table并指定聚合函数(比如求和):

wide_df = df.pivot_table(
    index="类别", columns="日期", values="数量",
    aggfunc="sum", fill_value=""
).reset_index()

二、Flask中展示表格的两种方式

方式1:转换后生成HTML直接渲染

在Flask视图函数中生成转换后的DataFrame,调用to_html生成HTML代码后传入模板:

from flask import Flask, render_template
import pandas as pd

app = Flask(__name__)

@app.route('/')
def show_table():
    # 生成wide_df的代码同上
    table_html = wide_df.to_html(classes="s-table", index=False)
    return render_template("table.html", table_html=table_html)

模板文件table.html:

<div class="s-table-container">
    {{ table_html|safe }}
</div>
  • |safe标记告诉Jinja2不要转义HTML标签,确保表格样式正常渲染。

方式2:直接用Jinja2渲染原始DataFrame(无需提前转换)

如果不想提前转换DataFrame,可以在视图中分组处理数据,再用Jinja2动态生成表格结构:

视图函数:

@app.route('/direct-table')
def show_direct_table():
    # 获取所有唯一日期并排序
    sorted_dates = sorted(df["日期"].unique())
    # 构建{类别: {日期: 数量}}的字典映射
    category_dict = df.groupby("类别").apply(
        lambda group: group.set_index("日期")["数量"].to_dict()
    ).to_dict()
    return render_template("direct_table.html", dates=sorted_dates, category_data=category_dict)

模板文件direct_table.html:

<div class="s-table-container">
    <table class="s-table">
        <thead>
            <tr>
                <th>类别</th>
                {% for date in dates %}
                <th>{{ date }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for category, count_map in category_data.items() %}
            <tr>
                <td>{{ category }}</td>
                {% for date in dates %}
                <td>{{ count_map.get(date, '') }}</td>
                {% endfor %}
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>

三、方案对比与推荐

  • Pandas转换方案:最简洁高效,代码量少,维护成本低,适合绝大多数场景。
  • Jinja直接渲染:适合需要动态调整表格结构的场景,但需手动处理分组和数据映射,代码稍复杂。
  • 存储两种格式:完全不推荐,既浪费存储空间,又会在数据更新时增加同步维护的成本,极易出错。

内容的提问来源于stack exchange,提问作者S.Slusky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:55:21