如何基于单列值将多个Pandas DataFrame并排展示?
问题描述
我有以下几个Pandas DataFrame:
import pandas as pd df = pd.DataFrame({'Name':["A"],'Level': [1],'Part':["Upper"]}) df1 = pd.DataFrame({'Name':["A","A"],'Level': [1,2],'Part':["Upper 2 System","Upper 2 stock"]}) df2 = pd.DataFrame({'Name':["ABC","ABC"],'Level': [1,3],'Part':["Upper System","Middle"]}) df3 = pd.DataFrame({'Name':["AAB","AAB","AAB"],'Level': [1,4,2],'Part':["Limits System","Deck","Ceiling"]})
它们的默认展示效果如下:
Name Level Part 0 A 1 Upper Name Level Part 0 A 1 Upper 2 System 1 A 2 Upper 2 stock Name Level Part 0 ABC 1 Upper System 1 ABC 3 Middle Name Level Part 0 AAB 1 Limits System 1 AAB 4 Deck 2 AAB 2 Ceiling
我需要将它们基于Name列分组并排展示,允许移除列标题,但必须保证各DataFrame块相互分隔,展示顺序无关。期望的展示样式如下:
Name Level Part Name Level Part Name Level Part 0 A 1 Upper 0 ABC 1 Upper System 0 AAB 1 Limits System 1 ABC 3 Middle 1 AAB 4 Deck Name Level Part 2 AAB 2 Ceiling 0 A 1 Upper 2 System 1 A 2 Upper 2 stock
实现方法
可以通过字符串拼接+对齐的方式实现这种横向并排展示,具体步骤如下:
- 合并并分组DataFrames
先把所有DataFrame合并到一个大表,再按Name分组,归集同属一个Name的所有行:
import pandas as pd # 定义原始DataFrames df = pd.DataFrame({'Name':["A"],'Level': [1],'Part':["Upper"]}) df1 = pd.DataFrame({'Name':["A","A"],'Level': [1,2],'Part':["Upper 2 System","Upper 2 stock"]}) df2 = pd.DataFrame({'Name':["ABC","ABC"],'Level': [1,3],'Part':["Upper System","Middle"]}) df3 = pd.DataFrame({'Name':["AAB","AAB","AAB"],'Level': [1,4,2],'Part':["Limits System","Deck","Ceiling"]}) # 合并所有DataFrame all_dfs = pd.concat([df, df1, df2, df3]).reset_index(drop=True) # 按Name分组,得到每个Name对应的行集合 grouped = all_dfs.groupby('Name')
- 生成对齐的并排文本
将每个分组的DataFrame转为字符串行,补全空白行对齐后横向拼接:
# 把每个分组的DataFrame转成按行拆分的字符串列表 name_blocks = {} for name, group in grouped: # 保留索引和列标题,转成字符串后按行拆分 block_lines = group.to_string(index=True, header=True).split('\n') name_blocks[name] = block_lines # 找出最长块的行数,用于补全空白行 max_line_count = max(len(lines) for lines in name_blocks.values()) # 给每个块补全空白行,确保所有块行数一致 for name in name_blocks: lines = name_blocks[name] if len(lines) < max_line_count: # 按块的第一行长度生成空白行 line_width = len(lines[0]) name_blocks[name] = lines + [' ' * line_width] * (max_line_count - len(lines)) # 横向拼接每行内容 result = [] for line_idx in range(max_line_count): current_line = ' '.join([name_blocks[name][line_idx] for name in name_blocks]) result.append(current_line) # 打印最终效果 print('\n'.join(result))
- 可选调整:移除重复列标题
如果不需要重复显示列标题,只需修改to_string的参数:
block_lines = group.to_string(index=True, header=False).split('\n')
运行代码后会输出符合需求的并排展示效果,示例输出:
Name Level Part Name Level Part Name Level Part 0 A 1 Upper 0 ABC 1 Upper System 0 AAB 1 Limits System 1 ABC 3 Middle 1 AAB 4 Deck 2 AAB 2 Ceiling 0 A 1 Upper 2 System 1 A 2 Upper 2 stock
内容的提问来源于stack exchange,提问作者Masood Khan
相关产品推荐
相关产品推荐

