如何将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
相关产品推荐
相关产品推荐

