Python中CSV字符串列结构化拆分与DataFrame构建问题
处理CSV复杂字符串字段的Python解决方案
以下是针对你遇到的CSV字符串处理问题的具体解决方法,基于df = pd.read_csv('TF1.csv')展开:
1. 将字符串结构化拆分为自定义列名的多列
如果字符串有固定格式,推荐用正则表达式提取替代split,避免因分隔符不一致导致的列长度不匹配问题。示例如下:
import pandas as pd df = pd.read_csv('TF1.csv') # 假设message列格式为 "2024-05-20 RA123 shipper={...}" # 用正则分组提取Date、RA及剩余内容,自定义列名 df[["Date", "RA", "remaining_content"]] = df["message"].str.extract(r'^(\S+) (\S+) (.*)$', expand=True)
说明:\S+匹配非空白字符,分组对应自定义列名,即使部分行匹配失败,也会生成NaN保证列长度一致。
2. 提取shipper字段的完整大括号内容到shipper列
针对跨多行的大括号内容,使用正则结合re.DOTALL标志捕获完整内容:
import re # 提取shipper=后的完整大括号内容(含换行) df["shipper"] = df["message"].str.extract(r'shipper=({.*})', flags=re.DOTALL)[0]
说明:flags=re.DOTALL让正则中的.匹配换行符,确保捕获跨多行的大括号内所有内容。
3. 将shipper字段的子项拆分为子列
先将shipper字符串转为Python字典,再用pd.json_normalize展开为子列:
import ast # 定义转换函数:将shipper字符串转为字典,替换"null"为Python的None def str_to_shipper_dict(s): if pd.isna(s): return {} # 替换JSON风格的"null"为Python可识别的None cleaned_str = s.replace('"null"', 'None') return ast.literal_eval(cleaned_str) # 转换shipper列为字典 df["shipper_dict"] = df["shipper"].apply(str_to_shipper_dict) # 展开字典为子列,并合并到原DataFrame shipper_subcols = pd.json_normalize(df["shipper_dict"]) df = pd.concat([df, shipper_subcols], axis=1)
说明:ast.literal_eval安全解析字符串为Python对象,pd.json_normalize自动将字典的键转为列名,列表类型字段(如names、TF)会保留原格式。
4. 基于单元格字符串创建自定义DataFrame或Schema
自定义DataFrame
提取所需字段后组合成新的DataFrame:
# 提取基础字段 df[["Date", "RA"]] = df["message"].str.extract(r'^(\S+) (\S+) ', expand=True) # 提取并展开shipper子列 df["shipper"] = df["message"].str.extract(r'shipper=({.*})', flags=re.DOTALL)[0] df["shipper_dict"] = df["shipper"].apply(str_to_shipper_dict) shipper_subcols = pd.json_normalize(df["shipper_dict"]) # 构建仅含目标字段的自定义DataFrame custom_df = pd.concat([df[["Date", "RA"]], shipper_subcols], axis=1)
指定Schema(数据类型)
通过astype为自定义DataFrame设置数据类型:
custom_df = custom_df.astype({ "Date": "datetime64[ns]", "ADR": "object", "phone": "object", "names": "object" })
关于split报错的说明
你遇到的ValueError: Columns must be same length as key,是因为部分行的字符串无法按指定分隔符拆分出足够的列数。改用正则str.extract可以避免这个问题,因为它会为匹配失败的行填充NaN,保证列长度与原DataFrame一致。
内容的提问来源于stack exchange,提问作者Amit Mistry
相关产品推荐
相关产品推荐

