XML转CSV后Pandas解析逗号分隔问题的解决咨询
嘿,这个问题我之前处理过类似的场景!其实两个阶段都能解决,但优先在XML转CSV的转换阶段处理是最省心、最高效的——从源头生成规范的CSV,比事后修复要靠谱得多,尤其是你说原文件特别大的情况下。我给你详细拆解两种方案:
解决方案:从源头修复优先,也可事后补救
一、最优方案:XML转CSV时直接生成规范格式
你遇到的问题本质是:当初转CSV时,没有对包含逗号的字段(比如txtDescricao里的内容)做引号包裹,导致Pandas读取时误把字段内的逗号当成了列分隔符。用Python自带的csv模块来生成CSV就能完美解决这个问题,它会自动处理带特殊字符的字段。
代码示例:XML转规范CSV
import xml.etree.ElementTree as ET import csv xml_path = "你的XML文件路径.xml" output_csv_path = "规范格式的输出.csv" # 解析XML tree = ET.parse(xml_path) root = tree.getroot() # 提取字段名(从第一个<despesa>节点里拿) field_names = [child.tag for child in root.find('dados').find('despesa')] # 写入CSV with open(output_csv_path, 'w', newline='', encoding='utf-8') as csv_file: # 用csv.writer自动处理引号,QUOTE_NONNUMERIC会给非数字字段加引号 writer = csv.writer(csv_file, quoting=csv.QUOTE_NONNUMERIC) # 先写表头 writer.writerow(field_names) # 遍历每个<despesa>节点写数据 for despesa in root.find('dados').findall('despesa'): row_data = [] for field in field_names: # 处理空值情况,避免报错 field_value = despesa.find(field).text if despesa.find(field) is not None else '' row_data.append(field_value) writer.writerow(row_data)
这段代码生成的CSV会自动给带逗号的字段加上双引号,比如:
name,number,sgUF,txtDescricao,year Romario,15,RJ,Consultoria,2018 Ronaldo,9,RJ,"Logistics, Search and Support",2018
这样Pandas用pd.read_csv()读取时,会正确识别这个带引号的字段,不会把里面的逗号当成列分隔符。
二、备选方案:修复已生成的问题CSV
如果已经有了错误的CSV文件,也能补救,但你的现有代码有两个小bug:
item.replace(',', '')没有重新赋值——Python字符串是不可变的,必须写成item = item.replace(',', '')才会生效;- 最后写入的
item是循环里data[:-1]的最后一个元素,不是原行的最后一个字段,导致列错位。
修复代码示例
import csv input_csv = 'dados_limpos_2018.csv' fixed_csv = 'dados_2018.csv' # 原CSV的正确列数是5:name, number, sgUF, txtDescricao, year EXPECTED_COLUMNS = 5 with open(input_csv, 'r', encoding='utf-8') as infile, open(fixed_csv, 'w', newline='', encoding='utf-8') as outfile: reader = csv.reader(infile) writer = csv.writer(outfile, quoting=csv.QUOTE_NONNUMERIC) # 先写入表头 header = next(reader) writer.writerow(header) for row in reader: if len(row) == EXPECTED_COLUMNS: # 行是正常的,直接写入 writer.writerow(row) else: # 行被拆分了:前3列是name/number/sgUF,最后1列是year,中间的都是txtDescricao的内容 fixed_row = [ row[0], row[1], row[2], ', '.join(row[3:-1]), # 把被拆分的txtDescricao内容合并回去 row[-1] ] writer.writerow(fixed_row)
这段代码会自动识别被拆错的行,把错位的内容合并回txtDescricao列,重新生成规范的CSV。
总结
- 优先选XML转CSV阶段处理:从源头生成符合标准的CSV,避免事后修复的麻烦,大文件处理起来也更高效;
- 要是只能处理现有CSV,用上面的修复代码也能搞定,但前提是你明确知道正确的列数和字段位置。
内容的提问来源于stack exchange,提问作者Costa.Gustavo
相关产品推荐
相关产品推荐

