如何读取表头列数不齐的CSV至Pandas并保留元数据?
解决带非等列元数据的CSV读取问题
针对设备生成的这类头部元数据行列数与数据行不一致的CSV读取需求,这里提供两种简便方法,既能保留所有元数据,又能构建目标的多级列索引DataFrame:
方法一:分两次读取(元数据+数据)
先单独提取头部元数据,再读取核心数据,最后将元数据整合到列的多级索引中:
import pandas as pd # 1. 读取前4行元数据 meta = pd.read_csv('12345.csv', nrows=4, header=None) meta_info = {} for _, row in meta.iterrows(): key = row[0].strip() values = [v.strip() for v in row[1:] if pd.notna(v)] meta_info[key] = values if len(values) > 1 else values[0] # 2. 读取数据部分(从第5行开始作为表头) df = pd.read_csv('12345.csv', header=4, index_col=0, parse_dates=True) # 3. 构建多级列索引 level_data = [] # 按元数据顺序生成每一层的列值,不足列数的重复填充 for key in ['Station', 'ID', 'elevation', 'units', 'time']: val = meta_info[key] level_data.append(val if isinstance(val, list) else [val]*len(df.columns)) df.columns = pd.MultiIndex.from_arrays(level_data, names=['Station', 'ID', 'elevation', 'units', 'time'])
方法二:一次性读取后拆分处理
适合元数据行数不固定的场景,先读取所有行再拆分处理:
import pandas as pd # 1. 读取所有行,不指定表头 all_content = pd.read_csv('12345.csv', header=None, skip_blank_lines=True) # 2. 拆分元数据和数据 meta_rows = all_content.iloc[:4] data_header = all_content.iloc[4].str.strip() data_rows = all_content.iloc[5:] # 3. 初始化数据DataFrame df = data_rows.set_axis(data_header, axis=1) df = df.set_index(data_header[0]).rename_axis(None) df.index = pd.to_datetime(df.index) df = df.apply(pd.to_numeric, errors='coerce') # 4. 构建多级列索引 levels = [] for _, row in meta_rows.iterrows(): key = row[0].strip() # 提取当前行的非空值,补全到数据列数 vals = [v.strip() if pd.notna(v) else key for v in row[1:]] while len(vals) < len(df.columns): vals.append(vals[0]) levels.append(vals) df.columns = pd.MultiIndex.from_arrays(levels, names=meta_rows[0].str.strip())
原方法报错原因
你最初使用header=[0,1,2,3,4]报错,是因为pandas要求指定的所有表头行必须有完全相同的列数,但你的CSV前3行只有2列,第4、5行有4列,列数不匹配导致触发Header rows must have an equal number of columns错误。
内容的提问来源于stack exchange,提问作者JC_CL
相关产品推荐
相关产品推荐

