新闻详情

新闻详情

首页 / 资讯中心 / 详情

CSV与Pandas高效数据处理:从读写到清洗合并的实践指南

发布时间:2026/10/1 3:31:51来源:尧图网络
CSV与Pandas高效数据处理:从读写到清洗合并的实践指南
1. 为什么这组搭配绕不开CSV 和 Pandas 的分工1.1 先看懂 CSV 的真面目CSVComma-Separated Values本质上就是一个纯文本文件每一行是一条记录每个字段用逗号分隔。它的历史能追溯到早期表格软件时代几十年下来依然是最通用的数据交换格式之一。我见过很多刚接触数据处理的同学一上来就纠结“为什么不用 Excel为什么不用数据库”其实答案很简单CSV 具备三个 Excel 没有的优势。第一它不依赖任何商业软件记事本能打开、命令行能读取、任何编程语言都有现成解析库。第二它是纯文本体积能压得很小一个几百万行的数据表也就是几十 MB 的事。第三它天然适合程序化处理你完全可以写一个脚本批量生成、批量修改、批量合并。换个角度看 CSV 其实很像“记账本的原始流水”Excel 则是你排版好、加好公式和颜色的精美账本而 Pandas 就是那个能一口气读完几百本流水账并帮你算出汇总的人。1.2 Pandas 补上了 CSV 的几个短板CSV 虽然通用但用起来有几个让人头大的问题类型全靠猜、中文编码容易乱、没有索引概念、几万行以上用 Excel 打开就卡。这些痛点 Pandas 基本全给你解决了。Pandas 读入 CSV 后会生成 DataFrame它最大的价值不是“能读取”而是“读进来之后你能马上做分析”。筛选、排序、分组、关联、透视、画图这些操作在原生 CSV 文件里想都不敢想但 DataFrame 里几行代码就能完成。再加上 read_csv 和 to_csv 这两个接口读写逻辑被封装得非常顺手你用 sep 指定分隔符、用 encoding 指定编码、用 dtype 指定列类型、用 parse_dates 指定时间列一次就能把一个乱七八糟的 CSV 转成结构规整的数据集。说实话处理 CSV 这件事本身并不难难的是“大量 CSV、多种格式、多套编码、还要反复清洗”的时候你还能保持逻辑清醒。Pandas 的价值就是把这堆琐碎操作收敛成一套固定套路让你把精力花在分析上。1.3 同场景下怎么选CSV、Excel 还是数据库很多人会问既然 CSV 这么简单为什么还要学 Pandas既然 Pandas 这么强为什么不干脆全都用数据库。我的建议是根据使用场景来选临时看数据、几十行、要给别人发报表用 Excel方便快捷。数据量大、要反复处理、要做批量合并用 Pandas 加 CSV灵活又高效。数据需要多用户并发写入、需要严格事务、需要权限控制上数据库MySQL 或 PostgreSQL 都可以。跨系统交换数据、导出备份、给第三方提供离线数据包CSV 永远是最不挑食的格式。在热词搜索里能看到“2023 年全国区县级手机信令数据 csv”“近十年全球地震发震情况.csv”这种典型数据它们往往来自某个行业系统批量导出数据量大、字段多样、还带各种噪声。这种场景就是 Pandas 的主场读进来、清洗、转换、聚合、再导出一气呵成。2. 手把手过一遍读写流程read_csv 与 to_csv 的常用参数2.1 读入文件时别让类型猜测坑了你read_csv 默认会根据每列的实际内容猜测数据类型这省事但也容易翻车。最典型的例子手机号码一列读进来变成了 int64科学计数法显示 1.38e10前面的 0 全丢了身份证号也变成了浮点数精度直接崩溃日期列变成了字符串排序和筛选全部失效。解决办法很简单读入时就用 dtype 参数把关键列锁死import pandas as pd df pd.read_csv( mobile_signal.csv, dtype{phone: str, user_id: str, district_code: str}, )如果嫌每次写 dtype 太啰嗦可以先读一小部分看一下每一列的真实情况再回过来反推正确的类型preview pd.read_csv(data.csv, nrows100) print(preview.dtypes)这里有个小经验凡是你觉得“这列可能有问题”的字段读入时一律先按字符串处理后面再按需转换。字符串能容忍前导零、长数字、特殊符号转换回来也很容易但数据一旦被误解成数值信息就永久丢失了谁也没法从 1.38e10 还原出一串手机号。关于数据类型转换日常工作里最常用的四件套是 astype、to_numeric、to_datetime、to_timedelta。其中 to_numeric 有个宝藏参数 errorscoerce转换失败时不会直接抛异常而是把异常值置成 NaN方便后面统一处理。时间列用 to_datetime同样可以传 errorscoerce。df[age] pd.to_numeric(df[age], errorscoerce) df[order_time] pd.to_datetime(df[order_time], errorscoerce) df[gender] df[gender].astype(category)2.2 导入细节编码、分隔符、表头与压缩格式CSV 文件在中文环境下最麻烦的问题就是编码。Windows 上 Excel 导出的 CSV 默认是 GBK 或 ANSI你用默认编码读入几乎必乱码。碰到乱码不要慌先试这几个编码按顺序来# 方案一GBKWindows 中文环境最常用 df pd.read_csv(report.csv, encodinggbk) # 方案二GB18030比 GBK 更全少数字符能救回来 df pd.read_csv(report.csv, encodinggb18030) # 方案三UTF-8 df pd.read_csv(report.csv, encodingutf-8)如果你完全不确定文件是什么编码用 chardet 先检测一下再决定用哪个编码读入pip install chardetimport chardet with open(report.csv, rb) as f: raw f.read(10000) result chardet.detect(raw) print(result[encoding])除了编码表头也是个容易踩坑的地方。默认情况下 read_csv 会把第一行当成列名但如果你的文件第一行是注释、说明或者空行就需要用 headerNone 手动指定或者用 skiprows 跳过前面几行。还有一个细节有些 CSV 是从系统导出的列名带空格、带百分号、甚至带不可见的 \ufeff 字符UTF-8 BOM读进来之后列名会多一个“看不见的前缀”排查起来特别隐蔽。我的习惯是读入后立刻把列名整体清洗一遍df.columns df.columns.str.strip().str.replace( r[^\w\u4e00-\u9fff], _ )分隔符是另一个常见坑。CSV 虽然叫“逗号分隔”但中文 CSV 里经常遇到用制表符\t、分号;甚至是竖线|分隔的文件。read_csv 的 sep 参数支持正则表达式比如 sepr[,;] 可以同时处理逗号和分号这在处理从异构系统导出的文件时非常实用。再说一个很多人忽略的能力read_csv 支持直接读取压缩包后缀的 CSV比如 .csv.gz、.csv.bz2、.csv.zip你完全不用先解压再读只要后缀是标准压缩格式pandas 会自动识别df pd.read_csv(big_data.csv.gz, compressioninfer, chunksize50000)这样既节省磁盘空间又省去解压步骤尤其适合日志类数据的日常处理。2.3 写出 CSV 时容易忽略的三个小问题很多人 read_csv 学得精细但 to_csv 总是丢三落四。最常见的三个问题分别是写出的文件自带索引列、中文乱码、字段里的逗号破坏了列结构。默认情况下 to_csv 会把 DataFrame 的索引也写成第一列最终文件里多了一个莫名其妙的 id 列。绝大多数场景下你都不需要它所以写出时记得加上 indexFalsedf.to_csv(output.csv, indexFalse, encodingutf-8-sig)encoding 推荐 utf-8-sig而不是 utf-8。这个带 BOM 的 UTF-8 格式对 Excel 最友好直接双击打开不会乱码如果你写 utf-8很多 Excel 版本会当成 ANSI 读中文全变乱码。给程序后续读入用的时候也可以用 utf-8-sig因为 pandas 读入时能自动去掉 BOM不影响使用。第三个坑是字段内容里的逗号和换行。如果数据里天然带逗号比如“北京市,朝阳区”直接写出会导致列错位。解决办法是给所有字段统一加引号pandas 里对应参数是 quotingcsv.QUOTE_ALL。必要的时候还可以把分隔符换成制表符一是能避开逗号冲突二是某些场景下用 vim 或者文本工具查看时更清晰import csv df.to_csv(output.tsv, sep\t, indexFalse, quotingcsv.QUOTE_ALL)3. 高效处理的几个关键动作合并、清洗与批量加载3.1 多个 CSV 合并glob 与 concat 的配合现实中数据很少只存在一个文件里更常见的是按天、按地区、按业务系统拆成几十上百个 CSV。热词里“怎么把多个 csv 格式的文件合并在一起”几乎是最长情的提问这里给一套我一直在用的标准做法。先用 glob 找到所有目标文件再用 pd.concat 合并。方向上有两个按行堆叠和按列拼接分别对应 concat 的 axis0 和 axis1import glob import pandas as pd files glob.glob(data/*.csv) df_list [] for f in files: df pd.read_csv(f, dtypestr) df_list.append(df) merged pd.concat(df_list, axis0, ignore_indexTrue)这里有几个细节值得多说一句。第一个细节是 dtypestr批量合并时如果各文件的同一列类型不一致合并后大概率会出脏数据统一按字符串读入最稳妥后面再统一转换。第二个细节是 ignore_indexTrueconcat 默认会保留原 DataFrame 的索引不处理的话合并后的索引会有大量重复后面一筛选就乱套。第三个细节是文件结构一致性理论上要合并的 CSV 应该有相同的列实际上却经常遇到某个文件多一列、少一列的情况合并后先检查一下列名差异print(set(merged.columns))如果用 concat 时确实存在列不一致行为是“列取并集、缺的填 NaN”。如果你想严格只保留共有的列可以先对所有 df 做个列名交集再统一切片。另外部分文件表头可能还有空行稳妥起见在循环里加一个 skiprows 参数或者读入后 dropna(howall) 兜底。3.2 数据清洗的标准套路重复值、缺失值与字符串说到 Pandas 必提数据清洗因为任何从真实业务系统导出的 CSV 都自带“脏数据”。我总结了一套四步清洗流程基本覆盖大多数场景。第一步去重。drop_duplicates 可以指定按哪些列判定重复不是所有列都一样才算重复。比如手机信令数据里一个用户在同一天可能被采集到多次你只想去掉完全一样的记录那就用全列如果想去掉同一号码的重复访问就按号码列df df.drop_duplicates(subset[phone, date], keepfirst)第二步处理缺失值。先搞清楚哪些列有缺失缺失占比多少再决定是删除还是填充print(df.isna().sum()) print(df.isna().mean()) df df.dropna(subset[phone]) # 关键字段缺失直接删 df[age] df[age].fillna(df[age].median()) # 数值列用中位数填充 df[remark] df[remark].fillna() # 文本列填空字符串第三步清洗字符串列。这个步骤最容易被忽略但也是最影响后续分析质量的。CSV 里的字符串经常带前后空格、全角空格、换行符、不可见字符直接筛选永远匹配不上。统一走一遍字符串清洗df[name] df[name].str.strip() df[note] df[note].str.replace(r\s, , regexTrue) df[city] df[city].str.replace(省, , regexFalse)第四步处理异常值。比如年龄出现 300 岁、金额出现负数这种逻辑上不合理的值要按业务规则过滤掉df df[(df[age] 0) (df[age] 120)] df df[df[amount] 0]数据清洗的核心原则我总结成一句话先理解业务再动数据。不要盲目把所有缺失值删掉也不要机械地把所有异常值改成默认值。清洗之前先搞清楚“这个字段在业务流程里代表什么、为什么可能缺失、缺失会影响什么分析”这样才能做出合理的取舍。3.3 大 CSV 分块处理用内存换时间之前先学会减负很多初学者处理大 CSV 时会遇到内存爆炸。比如文件有 2 GB读取时内存占用飙到 8 GB机器直接卡死。解决思路不是上更大内存而是学会“减负”和“分块”。先做减法。读入时只保留需要的列提前用 usecols 砍掉无关字段内存占用立减。第一步读入时只保留需要的列提前用 usecols 砍掉无关字段内存占用立减。忽略被 pandas 自动推断成了 object 的字符串列一般比数值列更占内存所以能用 category 的列尽量转成 categorydf pd.read_csv( large.csv, usecols[id, city, date, amount], dtype{id: str, city: category}, )再做分块。如果文件实在太大就按 chunksize 一块一块读逐块处理完再拼接结果。这里不建议把全部块 concat 回来除非你真的需要全量数据。多数场景下你要的只是统计结果那就边读边聚合result [] for chunk in pd.read_csv(large.csv, chunksize100000, dtypestr): chunk[amount] pd.to_numeric(chunk[amount], errorscoerce) result.append(chunk.groupby(city, as_indexFalse)[amount].sum()) final pd.concat(result, ignore_indexTrue).groupby(city, as_indexFalse)[amount].sum()我在处理“近十年全球地震发震情况.csv”这类公开数据集时也用过同样的手法几万到几十万行其实 pandas 都能一口吞下但一旦数据量到了千万级分块处理就不只是为了省内存更是为了错误隔离。某一块文件编码坏了、格式不对你只需要重跑那一个分片而不是整个流程推倒重来。4. 实操中高频踩坑与排查速查表既然是处理数据百分之八十的时间其实是在跟各种幺蛾子斗争。我这里把平时被问得最多、自己也踩过的坑集中整理一下按照“现象 - 原因 - 方案”的格式列出来可以直接当速查表用。4.1 安装与环境pandas 到底装到了哪里先聊最基础也最让人崩溃的问题pandas 怎么装。热词里就有“pycharm怎么安装pandas包”这几乎是每个新手都会遇到的坎。最简单的办法是用 pippip install pandas如果你用的是 Anaconda 环境也可以用 condaconda install pandas在 PyCharm 里安装走 File - Settings - Project - Python Interpreter点加号搜索 pandas 安装即可。这里容易出的问题不是安装本身而是“装完还是 import 失败”。绝大多数情况是你在 PyCharm 里选了一个解释器又在命令行里 pip install 到了另一个解释器两边根本不是同一个环境。排查方法是在 PyCharm 的 Python Console 里执行import sys print(sys.executable)再用命令行执行同样的命令对比两个路径是否一致。不一致的话就在 PyCharm 里把解释器切成你安装过 pandas 的那个。这个问题其实不算技术难题但能把人折腾整整一下午记住了能省很多时间。4.2 CSV 读写的典型故障乱码、类型错乱、并发写下面是真正的高频故障区每个都配了对应的处理方案。故障现象常见原因排查与解决读入中文变乱码文件编码与读入编码不匹配尝试 gbk、gb18030、utf-8或用 chardet 检测列名出现 \ufeff文件带 UTF-8 BOM用 utf-8-sig 编码读入或读入后 strip 列名手机号/ID 变成科学计数法被自动推断为数值类型读入时加 dtype{phone: str}日期列无法排序日期还是字符串类型pd.to_datetime 转换或用 parse_dates 参数写出文件 Excel 打开乱码用了 utf-8 没有带 BOM改用 encodingutf-8-sig写出文件多了一列 index没有关闭索引写出加 indexFalse读入时列数不对分隔符不是逗号或字段里有逗号检查 sep 参数必要时用 quoting 统一加引号字段中含逗号导致列错位未加引号写出写出时加 quotingcsv.QUOTE_ALL单独说说 C# 并发读写 CSV 的问题。热词里出现“c# csv 可同時寫入與讀取”和“c# csv 寫入 同時開啟唯獨”这类场景本质上是文件共享冲突跟 pandas 关系不大但值得提一嘴。CSV 是文本文件没有数据库的事务机制和行级锁一个进程在写、另一个进程在读读到的很可能是写到一半的半行甚至在 Windows 上文件被占用时直接报 IOException。实用的方案有好几种。最稳妥的是“写临时文件再替换”先写到一个临时文件名写完用 File.Replace 原子替换目标文件读者永远看不到中间状态。其次是给读写操作统一加一个跨进程的互斥锁比如命名 Mutex确保同一时刻只有一个写入者。如果对并发要求高、又要频繁读写我会建议直接换 SQLite一个文件同样轻量事务和锁机制都是现成的别在 CSV 上硬扛。4.3 与数据库来回折腾导入导出别硬扛CSV 经常作为数据库和数据分析系统之间的“搬运工”所以热词里才会有一堆“mysql导入csv文件”“postgresql导入csv文件语句”“labview csv转html”之类的问题。用 Pandas 往数据库里写最省事的方式是 to_sqlfrom sqlalchemy import create_engine engine create_engine(mysqlpymysql://user:passwordhost:port/dbname?charsetutf8mb4) df.to_sql(table_name, engine, if_existsappend, indexFalse, chunksize5000)但要注意大批量导入时 to_sql 往往不是最快的方案。MySQL 官方推荐的 LOAD DATA 比逐行 INSERT 快上好几倍PostgreSQL 的 COPY 命令同样效率极高。不过它们对 CSV 的格式要求更严格编码、分隔符、NULL 值表示、日期格式全都要对上不然导入到一半就会报错。所以我的习惯是先用 Pandas 做清洗和格式整理把目标 CSV 整理成数据库能接受的“干净格式”再交给 LOAD DATA 或 COPY 导入。反过来从数据库导出 CSV 时同样可以用 pandas 读取 SQL 再 to_csv这样编码、类型、表头都能按需求调整df pd.read_sql(SELECT * FROM table_name, engine) df.to_csv(export.csv, indexFalse, encodingutf-8-sig)把 Pandas 当作数据库和业务系统之间的“数据整形车间”比什么都直接在数据库里写 SQL 要灵活得多。这也是我处理数据量较大的业务报表时最常用的一条链路数据库导出 - pandas 清洗 - 转换成报告数据 - 再导出 CSV 给业务方。整套流程跑顺之后基本能做到“别人要数据一小时你只要一分钟”。最后分享一个我长期在用的习惯任何数据处理任务第一版代码里一定先把关键参数写到脚本最顶部比如文件路径、编码、分隔符、目标列、清洗规则后面调试时会发现省力非常多。数据处理这个活多数时间不是死在算法上而是死在细节上写清楚参数、保留中间结果、想到就加断言比什么都管用。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenRig:基于Node.js+tmux的Codex CLI本地代理调试方案 2026/10/1 5:28:39

OpenRig:基于Node.js+tmux的Codex CLI本地代理调试方案

1. 项目概述:OpenRig 是什么,它解决的是哪类真实问题?OpenRig 这个名字在当前技术社区中并不指向一个广为人知的、已发布成熟版本的开源项目——它没有官方 GitHub 主页、没有 npm 包注册记录、也没有主流技术文档站(如 docs.rs、…

阅读更多 →
Unity iOS手游Deep Link全链路实战:URL Scheme与Universal Links双通道集成 2026/10/1 5:28:38

Unity iOS手游Deep Link全链路实战:URL Scheme与Universal Links双通道集成

1. 项目概述:为什么 Deep Link 在 iOS 手游里不是“配菜”,而是“主菜” 你刚上线一款 Unity 开发的 iOS 手游,运营同学兴奋地发来一条短信链接:“快看!用户点这个链接,直接跳转到游戏内‘周年庆活动页’&…

阅读更多 →
Unity跨平台文件系统原理与实战避坑指南 2026/10/1 5:28:38

Unity跨平台文件系统原理与实战避坑指南

1. 项目概述:为什么Unity开发者必须啃下文件系统这根硬骨头你有没有遇到过这样的场景:在Windows上调试得好好的资源加载逻辑,一打包到Android就报“找不到StreamingAssets里的config.json”;或者iOS上PersistentDataPath返回的路径…

阅读更多 →
Agentic AI Infra生产级落地:编排、记忆、沙盒与可观测性实战 2026/10/1 5:28:38

Agentic AI Infra生产级落地:编排、记忆、沙盒与可观测性实战

1. 从云栖2026聊起:Agentic AI Infra到底在解决什么问题如果你最近在关注AI工程化这个方向,大概率会频繁刷到"Agentic AI Infra"这个词。云栖2026把"Agentic AI Infra,加速模型与智能体创新"作为核心议题之一&#xff0c…

阅读更多 →
Linux下RAR压缩解压工具安装实战:rarlinux-x64-6.1.b1.tar.gz指南 2026/10/1 5:28:38

Linux下RAR压缩解压工具安装实战:rarlinux-x64-6.1.b1.tar.gz指南

简介:一款面向Linux操作系统的六十四位RAR压缩工具6.1测试版资源包,适用于需要在主流Linux发行版上创建或提取RAR压缩档案的用户与运维人员。该版本为测试版,包含多卷压缩、自解压包生成、损坏档案修复、AES数据加密等新功能或改进&#xff0…

阅读更多 →
零基础补SP材质贴图:PBR原理与实操全流程 2026/10/1 5:28:29

零基础补SP材质贴图:PBR原理与实操全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉