Python处理CSV列不一致与编码问题
大家好,我们又见面了啊~本文《Python高效处理CSV列数不一致与编码问题》的内容中将会涉及到等等。如果你正在学习文章相关知识,欢迎关注我,以后会给大家带来更多文章相关文章,希望我们能一起进步!下面就开始本文的正式内容~

本文详细介绍了如何使用Python的csv模块处理大规模CSV文件中常见的列数不一致和UnicodeDecodeError问题。通过示例代码,演示了如何准确识别并报告不符合预期列数的行,包括逐行报告和将连续的异常行合并为范围报告的两种策略。教程强调了csv模块的优势、正确的文件编码处理以及数据清洗前的错误识别方法,旨在帮助用户提升数据预处理的效率和准确性。
处理CSV文件中的数据完整性与编码挑战
在数据处理流程中,尤其是当数据源自人工录入或不同系统导出时,CSV文件常常会出现各种格式问题。其中,最常见的挑战包括行与行之间列数不一致以及文件编码错误导致的UnicodeDecodeError。这些问题会严重阻碍数据导入到数据库(如Teradata)或进行后续分析。本教程将指导您如何利用Python的csv模块来高效地识别和报告这些问题,为后续的数据清洗奠定基础。
1. 理解问题根源
当CSV文件中的某些行包含的列数多于或少于预期时,通常是由于数据输入不规范、分隔符使用混乱或文本字段中包含未正确转义的分隔符。例如,如果一个CSV文件应有66列,但某些行只有65列或多达67列,这就会导致解析错误。
此外,UnicodeDecodeError: 'charmap' codec can't decode byte ... 错误通常发生在尝试以错误的字符编码读取文件时。例如,如果文件实际上是UTF-8编码,但尝试以默认的charmap(通常是操作系统的默认编码,如cp936或cp1252)读取,就会出现此错误。
简单的通过line.count(',')来计数分隔符的方法存在局限性,因为它无法正确处理包含逗号的带引号字段(例如"Hello, World"会被错误地计为两个逗号)。因此,使用Python内置的csv模块是更健壮和推荐的做法。
2. 使用Python csv 模块识别列数不一致的行
Python的csv模块专为处理CSV文件而设计,能够正确处理带引号的字段、不同分隔符和换行符。
2.1 准备工作与基本设置
在开始之前,您需要明确CSV文件预期的列数。例如,如果您的数据应该有66列,那么N_COLS就设置为66。
import csv # 定义预期的列数 N_COLS = 66 # 定义输入和输出文件名 INPUT_FILE = 'Data.csv' OUTPUT_REPORT_FILE = 'malformed_rows_report.csv'
2.2 逐行报告不符合预期的行
最直接的方法是遍历CSV文件的每一行,检查其解析后的列数是否与预期相符。如果不符,则记录该行的行号和实际列数。
import csv
# 定义预期的列数
N_COLS = 66
# 定义输入和输出文件名
INPUT_FILE = 'Data.csv'
OUTPUT_REPORT_FILE = 'malformed_rows_report.csv'
try:
with open(OUTPUT_REPORT_FILE, "w", newline='', encoding='utf-8') as f_out:
writer = csv.writer(f_out)
writer.writerow(["行号", "实际列数"]) # 写入报告头
# 注意:在这里指定正确的编码,例如 'utf-8' 或 'latin-1',以避免 UnicodeDecodeError
# newline='' 参数对于 csv 模块是必需的,以防止在 Windows 上出现额外的空行
with open(INPUT_FILE, "r", newline='', encoding='utf-8') as f_in:
reader = csv.reader(f_in)
# 跳过CSV文件的标题行(如果存在)
# 如果文件没有标题行,请注释掉或删除下一行
try:
header = next(reader)
# 如果需要,可以检查标题行的列数
if len(header) != N_COLS:
print(f"警告: 标题行 ({header}) 的列数 ({len(header)}) 与预期 ({N_COLS}) 不符。")
except StopIteration:
print("文件为空或只有标题行。")
# 如果文件只有标题行,我们可能不需要继续处理
# 可以选择在这里退出或继续,取决于具体需求
for i, row in enumerate(reader, start=1): # start=1 表示从数据行第一行开始计数
if len(row) != N_COLS:
writer.writerow([i, len(row)])
print(f"检测到异常行: 行号 {i}, 实际列数 {len(row)}")
print(f"异常行报告已生成到: {OUTPUT_REPORT_FILE}")
except FileNotFoundError:
print(f"错误: 输入文件 '{INPUT_FILE}' 未找到。")
except UnicodeDecodeError as e:
print(f"错误: 读取文件时发生编码问题。请尝试指定不同的编码 (例如 'latin-1')。详细信息: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
代码解析与注意事项:
- newline='': 这是使用csv模块时非常重要的参数,它能确保在不同操作系统上正确处理行结束符,并防止在写入时出现额外的空行。
- encoding='utf-8': 这是解决UnicodeDecodeError的关键。您需要根据实际文件的编码来设置此参数。常见的编码包括'utf-8'、'latin-1'、'gbk'等。如果遇到错误,请尝试不同的编码。
- csv.reader(f_in): 创建一个迭代器,它会逐行读取CSV文件,并根据逗号(默认分隔符)和引号规则解析每一行,将其转换为一个字符串列表。
- next(reader): 用于跳过CSV文件的标题行。如果您的文件没有标题行,请将其删除。
- enumerate(reader, start=1): 用于在迭代reader对象时同时获取行号。start=1确保行号从1开始,与用户习惯的行号对应。
- len(row): 获取当前行解析后的列数。
- 错误处理: 使用try-except块捕获FileNotFoundError和UnicodeDecodeError等常见错误,提高程序的健壮性。
2.3 优化报告:将连续异常行合并为范围
对于包含大量数据的CSV文件(如125,000行),逐行报告可能导致报告文件过大且难以阅读。更高效的方式是将具有相同异常列数的连续行合并为一个范围进行报告。
import csv
# 定义输入和输出文件名
INPUT_FILE = 'Data.csv'
OUTPUT_RANGES_FILE = 'malformed_ranges_report.csv'
def write_row_range(writer_obj, col_count, start_row, end_row):
"""
将列数、起始行和结束行写入报告。
如果起始行和结束行相同(单行异常),则结束行留空。
"""
if start_row == end_row:
writer_obj.writerow([col_count, start_row, ""])
else:
writer_obj.writerow([col_count, start_row, end_row])
try:
with open(OUTPUT_RANGES_FILE, "w", newline='', encoding='utf-8') as f_out:
writer = csv.writer(f_out)
writer.writerow(["实际列数", "起始行号", "结束行号"]) # 写入报告头
with open(INPUT_FILE, "r", newline='', encoding='utf-8') as f_in:
reader = csv.reader(f_in)
# 尝试读取标题行并确定期望的列数
try:
header_row = next(reader)
EXPECTED_COLS = len(header_row)
print(f"根据标题行确定预期列数为: {EXPECTED_COLS}")
except StopIteration:
print("错误: 文件为空或不包含数据行。无法确定预期列数。")
exit()
except Exception as e:
print(f"读取标题行时发生错误: {e}")
print("请手动设置 EXPECTED_COLS 变量或检查文件格式。")
# 如果无法从标题行确定,可以手动设置 EXPECTED_COLS
# 例如: EXPECTED_COLS = 66
exit()
# 初始化追踪状态
tracking = False
current_range_start_row = -1
current_range_cols_count = -1
total_rows_processed = 0
for i, row in enumerate(reader, start=1):
total_rows_processed = i # 记录当前处理到的总行数
current_row_cols = len(row)
if current_row_cols != EXPECTED_COLS: # 当前行是异常行
if not tracking: # 如果是新异常范围的开始
tracking = True
current_range_start_row = i
current_range_cols_count = current_row_cols
elif current_row_cols != current_range_cols_count: # 异常列数发生变化,结束前一个范围
write_row_range(writer, current_range_cols_count, current_range_start_row, i - 1)
# 开始新的异常范围
current_range_start_row = i
current_range_cols_count = current_row_cols
else: # 当前行是正常行
if tracking: # 如果之前正在追踪异常范围,现在结束它
write_row_range(writer, current_range_cols_count, current_range_start_row, i - 1)
tracking = False
current_range_start_row = -1
current_range_cols_count = -1
# 循环结束后,检查是否有未写入的异常范围
if tracking:
write_row_range(writer, current_range_cols_count, current_range_start_row, total_rows_processed)
print(f"异常行范围报告已生成到: {OUTPUT_RANGES_FILE}")
except FileNotFoundError:
print(f"错误: 输入文件 '{INPUT_FILE}' 未找到。")
except UnicodeDecodeError as e:
print(f"错误: 读取文件时发生编码问题。请尝试指定不同的编码 (例如 'latin-1')。详细信息: {e}")
except Exception as e:
print(f"发生未知错误: {e}")代码解析与注意事项:
- EXPECTED_COLS: 在这个版本中,我们尝试从CSV文件的第一行(通常是标题行)动态确定预期的列数。这对于那些列数不确定但标题行是标准的情况非常有用。如果标题行本身就不标准,您可能需要手动设置EXPECTED_COLS。
- tracking 标志: 用于指示当前是否正在追踪一个异常行范围。
- current_range_start_row 和 current_range_cols_count: 分别记录当前异常范围的起始行号和该范围内的列数。
- write_row_range 函数: 这是一个辅助函数,用于将识别到的异常范围写入报告。它会判断是单行异常还是多行范围。
- 逻辑流程:
- 当遇到一个与EXPECTED_COLS不符的行时:
- 如果tracking为False,说明这是一个新异常范围的开始。
- 如果tracking为True但current_row_cols与current_range_cols_count不同,说明当前异常列数发生了变化,需要结束前一个范围并开始新的范围。
- 当遇到一个与EXPECTED_COLS相符的正常行时:
- 如果tracking为True,说明之前正在追踪的异常范围已经结束,需要将其写入报告。
- 当遇到一个与EXPECTED_COLS不符的行时:
- 循环结束后的处理: 在for循环结束后,需要再次检查tracking标志。如果它仍然为True,说明最后一个异常范围直到文件末尾,需要将其写入报告。
3. 总结与最佳实践
通过上述Python脚本,您可以有效地识别CSV文件中列数不一致的问题,并生成易于分析的报告。这对于数据清洗和数据导入前的预处理至关重要。
关键注意事项:
- 编码问题: UnicodeDecodeError是常见问题。始终尝试使用encoding='utf-8'打开文件。如果失败,尝试'latin-1'或其他可能的编码。有时候,数据源会使用'gbk'或'cp936'等本地编码。
- csv模块的强大功能: 避免手动通过split(',')或count(',')来解析CSV文件,因为它们无法正确处理包含逗号的带引号字段。csv模块是处理此类复杂性的标准工具。
- 数据清洗策略: 这些脚本主要用于识别和报告问题,而不是“当场修复”。对于大规模的脏数据,通常的流程是:
- 报告: 使用本教程的方法生成详细的异常报告。
- 分析: 根据报告分析异常行的模式和原因。
- 修复: 根据分析结果,可以手动编辑原始文件,或者编写更复杂的Python脚本来自动化修复(例如,填充缺失的列,或截断多余的列)。
- 验证: 修复后再次运行报告脚本,确保问题已解决。
- 分隔符: 如果您的CSV文件不使用逗号作为分隔符(例如,使用分号或制表符),您可以在csv.reader中通过delimiter参数指定,例如csv.reader(f_in, delimiter=';')。
通过遵循这些指导原则和使用提供的Python代码,您可以显著提高处理复杂CSV数据的效率和准确性,确保数据在进入下游系统前具备更高的质量。
今天关于《Python处理CSV列不一致与编码问题》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
PHP项目部署到Windows服务器教程
- 上一篇
- PHP项目部署到Windows服务器教程
- 下一篇
- Java抽象方法详解与使用技巧
-
- 文章 · python教程 | 1分钟前 |
- Pythonpdb调试方法详解
- 109浏览 收藏
-
- 文章 · python教程 | 9分钟前 |
- Pyodide集成BasthonTurtle教程与SVG渲染详解
- 447浏览 收藏
-
- 文章 · python教程 | 16分钟前 |
- Pythontkinter添加控件技巧分享
- 148浏览 收藏
-
- 文章 · python教程 | 45分钟前 |
- KBar快捷键注册失败怎么解决
- 392浏览 收藏
-
- 文章 · python教程 | 57分钟前 |
- Python多目录导入技巧与实战解析
- 423浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python局部变量定义与使用技巧
- 182浏览 收藏
-
- 文章 · python教程 | 1小时前 | 类 自定义行为 双下划线 Python魔法方法 特殊方法
- Python常用魔法方法有哪些?
- 300浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- CP-SAT求解器进度与优化分析
- 310浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python文件读写操作全解析
- 355浏览 收藏
-
- 文章 · python教程 | 2小时前 | 列表 字典 元组 集合 Python3数据类型
- Python3常见数据类型有哪些?
- 260浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3176次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3388次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3417次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4522次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3796次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览

