如何用Pandas导入含可变大小子块的多份CSV文件?
搞定可变CSV子块的简便方法
嘿,这个场景我太熟了!用skiprows确实搞不定这种不规则的子块,不过既然你已经知道每个子块左上角的标记值(比如a和d),咱们直接按标记定位子块边界就完事了,思路清晰还好用:
核心步骤
- 先把整个CSV文件的所有行读出来,这样能遍历每一行精准找标记
- 定位每个标记行的索引,以此划分出每个子块的起始和结束位置
- 把每个子块的行单独提取出来,交给pandas读取成DataFrame
完整代码示例
直接上能跑的代码,你可以根据自己的文件调整细节:
import pandas as pd from io import StringIO # 1. 读取整个文件的所有行,顺便去掉空行和无效垃圾行 with open('your_csv_file.csv', 'r', encoding='utf-8') as f: all_lines = [line.strip() for line in f.readlines() if line.strip()] # 2. 定义子块起始标记,以及对应的表头(如果标记行本身就是表头,这里可以直接用标记行内容) # 对应你示例里的'a'表头是a,b,c,'d'表头是d,z,e,f block_markers = { 'a': ['a', 'b', 'c'], 'd': ['d', 'z', 'e', 'f'] } # 3. 找出所有子块的起始行索引和对应标记 block_positions = [] for line_idx, line_content in enumerate(all_lines): # 取每行的第一个单元格(分割后去空格) first_cell = line_content.split(',')[0].strip() if first_cell in block_markers: block_positions.append( (line_idx, first_cell) ) # 4. 逐个提取子块并转成DataFrame result_dfs = {} for i in range(len(block_positions)): start_idx, marker = block_positions[i] # 确定子块结束行:下一个标记的前一行,或者文件最后一行 if i < len(block_positions) - 1: end_idx = block_positions[i+1][0] - 1 else: end_idx = len(all_lines) - 1 # 提取当前子块的所有行 block_lines = all_lines[start_idx : end_idx + 1] # 用StringIO把行转换成pandas能读取的"虚拟文件" df = pd.read_csv( StringIO('\n'.join(block_lines)), header=0, # 第一行作为表头 names=block_markers[marker] # 强制指定表头,避免格式错乱 ) result_dfs[marker] = df # 现在就能直接调用每个标记对应的DataFrame了 print("子块a的内容:") print(result_dfs['a']) print("\n子块d的内容:") print(result_dfs['d'])
实用小细节
- 子块之间的垃圾行(比如
//// junk)会自动被排除,因为我们只提取两个标记之间的有效行 - 如果标记行的表头有多余空格或格式不一致,提前用
strip()处理即可 - 如果子块的表头就是标记行本身,也可以不用指定
names,让pandas自动识别表头
内容的提问来源于stack exchange,提问作者00__00__00
相关产品推荐
相关产品推荐

