如何聚合DataFrame使指定列值保留在独立单元格?
Pandas实现类似Excel合并单元格的分组展示效果
问题背景
现有如下Pandas DataFrame:
import pandas as pd data = { 'sto_num': [1, 1, 1, 2, 2, 3, 3], 'sto_text': ['ab', 'ab', 'ab', 'k', 'k', 'b', 'b'], 'tu_num': [2.2, 2.6, 3.5, 1.2, 1.3, 5.2, 5.1], 'compliance': ['С', 'Н', 'Ч', 'С', 'Н', 'С', 'Ч'], 'comment': ['с1', 'н1', 'ч1', 'с2', 'н2', 'с3', 'ч3'] } df = pd.DataFrame(data)
原代码尝试通过groupby聚合将同组值合并到单个单元格,但需求是保留每行独立记录,仅在视觉上对sto_num列的重复值进行合并展示,类似Excel的合并单元格效果,同时疑问:DataFrame能否像Excel那样不同列拥有不同行数?
核心结论
Pandas DataFrame是严格的二维表格结构,每行的列数必须一致,无法实现某列单独多行的底层结构,但可以通过以下两种方式实现类似的视觉效果:
方法1:Jupyter Notebook中显示时合并重复单元格
通过Pandas的style功能自定义CSS样式,隐藏重复的sto_num单元格,仅显示每组的第一个值,视觉上实现合并效果,底层数据保持完整:
def merge_duplicate_display(df, target_col): col_idx = df.columns.get_loc(target_col) + 1 # CSS选择器从1开始计数 styles = [] # 遍历每个分组的索引范围 for val, idx_list in df.groupby(target_col).groups.items(): if len(idx_list) <= 1: continue # 设置第一个单元格垂直居中并占据多行高度 styles.append({ 'selector': f'tbody tr:nth-child({idx_list[0]+1}) td:nth-child({col_idx})', 'props': [ ('vertical-align', 'middle'), ('border-bottom', 'none'), ('height', f'{len(idx_list)*30}px') ] }) # 隐藏同组的其他单元格 for idx in idx_list[1:]: styles.append({ 'selector': f'tbody tr:nth-child({idx+1}) td:nth-child({col_idx})', 'props': [('display', 'none')] }) return df.style.set_table_styles(styles) # 应用样式并显示 styled_df = merge_duplicate_display(df, 'sto_num') styled_df
方法2:导出到Excel时保留合并单元格
如果需要将结果导出为Excel文件并保留合并效果,可使用xlsxwriter引擎手动设置合并单元格:
with pd.ExcelWriter('grouped_output.xlsx', engine='xlsxwriter') as writer: df.to_excel(writer, sheet_name='Result', index=False) workbook = writer.book worksheet = writer.sheets['Result'] # 遍历数据行,合并sto_num列的重复值 prev_sto = None start_row = 1 # 表头行索引为0,数据从第1行开始 total_rows = len(df) for row in range(1, total_rows + 1): current_sto = df.iloc[row-1]['sto_num'] if current_sto != prev_sto: if prev_sto is not None: # 合并从start_row到当前行前一行的单元格 worksheet.merge_range(f'A{start_row}:A{row-1}', prev_sto) prev_sto = current_sto start_row = row # 处理最后一组数据 worksheet.merge_range(f'A{start_row}:A{total_rows}', prev_sto)
注意事项
- 不要使用
groupby聚合合并单元格,这会丢失原始行结构,不符合需求; - 上述方法仅改变展示/导出效果,底层DataFrame的每行记录保持独立,不影响后续数据分析操作。
内容的提问来源于stack exchange,提问作者user24958090
相关产品推荐
相关产品推荐

