Python pandas如何加载特殊结构CSV文件并实现数据透视
问题场景
使用pd.read_csv()加载csv文件时,第五列Data_Series存在格式聚合问题:单字段内存储了多行以分号分隔的数值,数值使用逗号作为小数分隔符,示例内容如下:
0; 0,5; 1; 2; 4; 6 12; 15; 25; 33; 23 0; 0,3; 2; 3; 7; 8; 8,5; 9,5 22; 45; 35; 48; 55; 60; 62; 58
目标输出为5列结构的DataFrame,将原Statistic列透视为X、Y两个字段,分别承载Data_Series中按行配对的数值。
实现方案
核心思路
先完整读入异常列保留原始字符串,再单独拆分解析聚合内容,最后做透视重组得到目标结构,避免加载阶段自动拆分导致列错位。
具体步骤
- 加载文件时指定
Data_Series列为字符串类型,关闭pandas对该列的自动拆分逻辑 - 清洗
Data_Series内容:将逗号小数替换为通用点号格式,按换行符拆分多行序列,每连续两行为一组(第一行是X轴序列、第二行是对应Y轴序列) - 按分号拆分每组序列、转为浮点型,按位置对齐X、Y值配对
- 将解析后的数据展开为长表,再按
Statistic字段透视得到最终宽表结构
参考代码
import pandas as pd # 加载文件,若原始文件本身用分号做列分隔符,额外加参数 sep=";" df = pd.read_csv("your_file_path.csv", dtype={"Data_Series": str}) def parse_series(content): # 统一小数格式、拆分多行 lines = content.replace(",", ".").strip().split("\n") paired_data = [] # 每两行一组配对X/Y for idx in range(0, len(lines), 2): # 拆分X值、过滤空值 x_list = [float(v.strip()) for v in lines[idx].split(";") if v.strip()] # 拆分Y值、过滤空值 y_list = [float(v.strip()) for v in lines[idx+1].split(";") if v.strip()] # 按最短长度对齐配对,避免长度不匹配报错 match_len = min(len(x_list), len(y_list)) for x, y in zip(x_list[:match_len], y_list[:match_len]): paired_data.append({"X": x, "Y": y}) return paired_data # 解析并展开数据 df["parsed_pair"] = df["Data_Series"].apply(parse_series) df = df.explode("parsed_pair").reset_index(drop=True) # 拆分X、Y字段,删除原始异常列 df = pd.concat( [df.drop(["Data_Series", "parsed_pair"], axis=1), df["parsed_pair"].apply(pd.Series)], axis=1 ) # 透视得到最终5列结构,index参数传入除Statistic/X/Y外的所有业务主键列 final_df = df.pivot( index=[col for col in df.columns if col not in ["Statistic", "X", "Y"]], columns="Statistic", values=["X", "Y"] ).reset_index() # 扁平化列名 final_df.columns = [f"{stat}_{axis}" if stat else axis for axis, stat in final_df.columns]
注意事项
- 如果原始csv文件本身用分号作为列分隔符,加载时必须指定
sep=";"参数,同时确认Data_Series被识别为单独一列 - 解析逻辑默认
Data_Series内X/Y序列成对出现(总行数为偶数),如果存在缺行需要在解析函数中加补空/跳过逻辑 - 如果数值中同时存在逗号作千分位的情况,需要先替换千分位逗号再处理小数分隔符,避免转换报错
内容的提问来源于stack exchange,提问作者Susy84
相关产品推荐
相关产品推荐

