如何用Python从CSV生成带边框表格并转换数据格式
解决CSV格式转换与带边框表格生成问题
我来帮你搞定这两个Python处理表格的需求,分两部分来讲解:
一、将CSV转换为目标宽格式
你的输入是长格式的CSV,需要转换成以indiv_number为行、基因为列的宽格式。这里提供两种实现方式,用pandas更高效,纯Python则不需要额外依赖:
方法1:使用pandas(推荐)
pandas的透视表功能能快速完成长转宽的操作,代码简洁易维护:
import pandas as pd # 读取输入CSV df = pd.read_csv('input.csv') # 生成宽表:行是indiv_number,列是基因名,值是to_append,缺失值填充默认值 pivot_df = df.pivot( index='indiv_number', columns='genename', values='to_append' ).fillna('[0000]') # 这里的默认值可以根据你的需求修改 # 构建目标格式的输出内容 output = [] # 第一行:所有基因名 output.append(' '.join(pivot_df.columns)) # 第二行:标题行 output.append('indiv_number') # 后续每行:个体编号 + 对应基因的to_append值 for indiv_id, row in pivot_df.iterrows(): output_line = f"{indiv_id} {' '.join(row.values)}" output.append(output_line) # 写入文件或打印结果 with open('output.txt', 'w') as f: f.write('\n'.join(output)) print('\n'.join(output))
方法2:纯Python实现(无依赖)
如果不想安装pandas,用标准库也能实现:
from collections import defaultdict # 读取并解析CSV数据 gene_data = defaultdict(dict) all_genes = set() with open('input.csv', 'r') as f: # 跳过表头 next(f) for line in f: indiv_num, gene, append_val = line.strip().split(',') gene_data[int(indiv_num)][gene] = append_val all_genes.add(gene) # 对基因和个体编号排序,保证输出顺序一致 sorted_genes = sorted(all_genes) sorted_indivs = sorted(gene_data.keys()) # 构建输出内容 output = [] output.append(' '.join(sorted_genes)) output.append('indiv_number') for indiv_id in sorted_indivs: # 按基因顺序取对应的值,缺失则用默认值 row_values = [gene_data[indiv_id].get(gene, '[0000]') for gene in sorted_genes] output.append(f"{indiv_id} {' '.join(row_values)}") # 保存或打印 with open('output.txt', 'w') as f: f.write('\n'.join(output)) print('\n'.join(output))
二、生成带边框的表格
生成带边框的表格有两种常用方式:用第三方库快速实现,或者手动拼接自定义边框。
方法1:使用tabulate库(推荐)
tabulate是专门用来生成美观表格的库,支持多种边框格式。先安装:
pip install tabulate
然后基于转换后的宽表生成带边框表格:
from tabulate import tabulate import pandas as pd # 读取并转换数据 df = pd.read_csv('input.csv') pivot_df = df.pivot( index='indiv_number', columns='genename', values='to_append' ).fillna('[0000]').reset_index() # 把indiv_number转为普通列 # 生成grid格式的带边框表格,还可以选'pipe'(Markdown表格)、'html'等格式 bordered_table = tabulate(pivot_df, headers='keys', tablefmt='grid') print(bordered_table)
输出示例:
+----------------+----------+----------+----------+ | indiv_number | gene1 | gene2 | gene3 | +================+==========+==========+==========+ | 0 | [000011] | [101010] | [0101010]| +----------------+----------+----------+----------+ | 1 | [0101010]| [0101010]| [0000] | +----------------+----------+----------+----------+
方法2:手动拼接边框(无依赖)
如果不想用第三方库,可以自己计算列宽并拼接边框:
import pandas as pd # 读取并转换数据 df = pd.read_csv('input.csv') pivot_df = df.pivot( index='indiv_number', columns='genename', values='to_append' ).fillna('[0000]').reset_index() # 获取表头和数据行 headers = list(pivot_df.columns) data_rows = pivot_df.values.tolist() # 计算每列的最大宽度,保证边框对齐 col_widths = [] for col_idx in range(len(headers)): # 取表头和该列所有数据的最大长度 max_len = max(len(str(headers[col_idx])), max(len(str(row[col_idx])) for row in data_rows)) col_widths.append(max_len) # 生成顶部/底部边框 border = '+' + '+'.join(['-'*(width + 2) for width in col_widths]) + '+' # 生成表头行 header_line = '| ' + ' | '.join([header.ljust(width) for header, width in zip(headers, col_widths)]) + ' |' # 生成数据行 data_lines = [] for row in data_rows: line = '| ' + ' | '.join([str(val).ljust(width) for val, width in zip(row, col_widths)]) + ' |' data_lines.append(line) # 拼接所有部分 final_table = '\n'.join([border, header_line, border] + data_lines + [border]) print(final_table)
这段代码会生成和tabulate类似的grid格式表格,完全自定义,不需要任何第三方依赖。
内容的提问来源于stack exchange,提问作者Zainab Khateeb
相关产品推荐
相关产品推荐

