如何解决Pandas读取含未闭合双引号的CSV列异常问题
解决CSV解析时引号后内容合并到单列的问题
问题重现
你的input.csv每条记录的第5个字段以双引号开头,但没有闭合引号,示例内容:
1,abc,65.0,en-GB,"reverted,Knowledge Alert,ab00998978,1,Y,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 2,zolhOgdmpwAQjfaUONdTD7,15.0,en-GB,"New & Dropped Routes,Article,KM100015050,2,N,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 3,zolhOgdmpwAQjfaUONdTD7,4.0,en-GB,"New & Dropped Routes,Article,KM100015050,3,N,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
使用默认参数的Pandas代码读取时:
import pandas as pd entity_df = pd.read_csv(entity_control_source_path, header=0, sep=",", quotechar='"', dtype=str)
会导致引号后的所有内容被合并到单个列中,无法正确分割字段。
原因分析
Pandas的read_csv默认通过quotechar识别被包裹的字段,当字段只有开头引号没有闭合时,解析器会认为从开头引号到行尾的所有内容都是同一个字段,字段内的逗号不再被视为分隔符,最终导致后续列全部合并。
解决方案
方案1:修复源CSV文件(推荐)
这是最根本的解决方法,给每条记录的末尾补充闭合的双引号,让CSV格式符合规范:
1,abc,65.0,en-GB,"reverted,Knowledge Alert,ab00998978,1,Y,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,," 2,zolhOgdmpwAQjfaUONdTD7,15.0,en-GB,"New & Dropped Routes,Article,KM100015050,2,N,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,," 3,zolhOgdmpwAQjfaUONdTD7,4.0,en-GB,"New & Dropped Routes,Article,KM100015050,3,N,Y,default,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
修改后再用原代码读取,就能正确分割所有字段。
方案2:修改Pandas读取参数
如果无法修改源文件,可以调整read_csv的参数,让解析器忽略引号的特殊作用:
import pandas as pd import csv # 关闭引号解析,将引号视为普通字符 entity_df = pd.read_csv( entity_control_source_path, header=0, sep=",", quoting=csv.QUOTE_NONE, # 不识别引号包裹的字段 quotechar=None, # 禁用quotechar dtype=str )
这个方法会把引号当成普通字符,同时正确分割所有逗号分隔的字段,但注意原引号内的逗号也会被当成分隔符——如果你的需求是保留引号内的逗号作为字段内容,那这个方法不适用,必须用方案1。
方案3:自定义行解析逻辑
如果需要保留引号内的逗号作为字段内容,但又无法修改源文件,可以手动逐行解析:
import pandas as pd data = [] with open(entity_control_source_path, 'r', encoding='utf-8') as f: header = f.readline().strip().split(',') for line in f: line = line.strip() # 分割为:引号前的部分 + 引号内的部分 parts = line.split('"', 1) prefix = parts[0].split(',')[:-1] # 引号前的字段 quoted_content = parts[1] if len(parts) > 1 else '' suffix = quoted_content.split(',') # 引号内的内容按逗号分割 full_row = prefix + suffix # 补全缺失的空列(匹配header长度) full_row += [''] * (len(header) - len(full_row)) data.append(full_row) entity_df = pd.DataFrame(data, columns=header, dtype=str)
这个方法会手动拆分每行,把引号前的字段和引号内的内容合并成完整的行,适合需要保留引号内逗号的场景。
内容的提问来源于stack exchange,提问作者kalpana
相关产品推荐
相关产品推荐

