news 2026/10/6 19:53:43

Pandas处理CSV实战:从安装踩坑到分块存储优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pandas处理CSV实战:从安装踩坑到分块存储优化

处理CSV这活儿,我大概写了得有八九年了。从最早用Excel打开一个200MB的文件卡到无响应,到后来换用Pandas几秒钟读完,再把结果写回CSV供业务部门复用——这个切换几乎是每个做数据分析的人都会经历的坎。今天这篇不打算讲那种官方文档式的API大全,而是把我实际用Pandas处理CSV存储时的完整链路,从安装踩坑、读入参数、清洗转换,到分块优化、存储选型,一整套真实可复现的流程放出来。无论你是刚装好Pandas还没跑通第一个pd.read_csv,还是已经在处理百万级数据但总觉得内存紧张,这篇应该都有对应能直接抄的东西。

1. 安装与版本那些坑:先让pandas在环境里完整跑起来

1.1 清华源报错"could not find a version"的完整排查

搜索引擎里这个报错出现频率极高,ERROR: Could not find a version that satisfies the requirement pandas (from versions: none),后面还跟着一句No matching distribution found。很多人看到这串英文就以为是网络断了,其实多数情况不是。

我第一次遇到这问题,是在一台装了Python 3.12的老电脑上,当时的pandas稳定版还停留在2.1.x,官方还没放出适配3.12的wheel包。pip install pandas去PyPI上查找时发现没有兼容当前Python版本的编译产物,干脆一个版本都不报给你,直接提示from versions: none。这就是"裸奔的Python版本"和"尚未跟进构建的pandas"之间常见的时间差。

排查步骤按顺序做,基本能定位到九成的问题:

  1. 先看Python版本:python --version,确认是3.9、3.10、3.11还是3.12。不同版本对应的pandas构建覆盖面不一样。
  2. 再升级pip:python -m pip install --upgrade pip。旧版pip解析依赖的能力弱,有时明明有兼容版本却找不到。
  3. 确认当前pandas支持的版本范围。pandas 2.x系列在较新的Python上构建及时,但如果你卡在Python 3.8或3.7,pip只会去匹配旧版pandas,容易撞见依赖冲突。
  4. 指定清华源时也要看报错细节:
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

清华源本身是很稳的,但如果镜像同步存在延迟,刚发布的pandas版本可能还没被同步上去。这时加上--timeout 60或换阿里源、中科大源多试一次,往往就通了。

真正稳定可复现的解决路径是:创建虚拟环境时就把Python版本和对齐的pandas版本锁好。比如我现在的项目里统一用Python 3.10 + pandas 2.0.x,三个环境装了三四次,从没再被这个报错困扰过。建议没有特殊需求的读者直接无脑上Python 3.10或3.11,兼容性面最广。

  • 检查Python位数:python -c "import platform; print(platform.architecture())",32位Python对大文件操作的内存上限低很多,CSV处理快不起来。
  • 检查是否装错环境:pip -V看pip指向的site-packages路径,很多人装了包却调不出来,就是环境混了。
  • 用pip list | grep pandas确认已安装版本和来源。

1.2 手机与不含pip的桌面环境里装pandas的注意点

现在不少人会用手机写Python练习,或者在一些受限办公电脑上装环境。手机端如果用的是Termux这类Linux终端模拟器,直接pip install pandas通常可行,但需要先装好build-essential、python-dev等编译工具,因为部分依赖在ARM架构上没有预编译wheel,需要现场编译,耗时可能很长,还容易中途失败。更省事的方式是用Pydroid 3这类自带pandas预装包的应用,打开就能跑import pandas as pd。

还有些正版办公电脑不开放外网源,或者连pip都无法使用。这时可以从PyPI的wheel页面手动下载pandas的.whl文件,拷贝到目标机器上用pip install ./pandas.whl离线安装。需要留意pandas依赖numpy、python-dateutil、pytz、tzdata这几个包,缺哪个补哪个。离线装过一次之后,建议用pip download -r requirements.txt -d ./offline_pkgs把常用包全部留存,下次就快了。

# 离线下载完整依赖 pip download pandas -d ./offline_pkgs -i https://pypi.tuna.tsinghua.edu.cn/simple # 目标机器安装 pip install ./offline_pkgs/*

2. 读入CSV前先搞明白:编码、分隔符与类型推断

2.1 编码问题用utf-8-sig一招解决

CSV文件的编码问题是我见过的新手翻车重灾区。明明文件里是中文数据,pd.read_csv('数据.csv')一跑,出来一堆乱码,或者直接报UnicodeDecodeError。原因很直接:read_csv默认用UTF-8解码,而国内很多系统导出的CSV用的是GBK/GB2312编码,Windows下的Excel另存为CSV时尤其常见。

真正稳妥的做法是读入时显式指定编码:

import pandas as pd df = pd.read_csv('业务数据.csv', encoding='utf-8-sig')

如果是Excel导出的文件,通常编码是ANSI也就是GBK,可以改用encoding='gbk'。我自己的经验是先用utf-8-sig试,不行再换gbk。utf-8-sig和普通utf-8的区别在于,它会自动处理文件开头的BOM标记,避免读出来后第一列列名变成\ufeff列名这种情况。Excel导出UTF-8 CSV时经常带BOM,所以统一用utf-8-sig读最省心。

遇到连编码都无法确定的文件,不要瞎猜,直接用二进制打开看前几十个字节:

with open('未知.csv', 'rb') as f: raw = f.read(100) print(raw)

如果字节里出现大量连续的两个字节表示一个汉字,且没有\xef\xbb\xbf开头,大概率是GBK。也可以用chardet库自动检测,实测准确率尚可,但中文短文本时会抽风,最终还是靠试。

2.2 分隔符不只是逗号:从sep到正则表达式

CSV里的字母C是Comma,但现实世界里的分隔符千奇百怪。欧洲某些系统导出的数据用分号;,日志文件用制表符\t,还有些老系统用竖线|。最坑的是:明明数据里字段值本身就包含逗号,比如地址"北京市,朝阳区",如果不加引号包裹,读进来就会多出一列,整行数据全乱。

read_csv中等号左边的sep参数就是干这个的:

# 分号分隔 df = pd.read_csv('data.csv', sep=';') # 制表符 df = pd.read_csv('data.tsv', sep='\t') # 空格分隔(多个连续空格压缩) df = pd.read_csv('data.txt', sep=r'\s+')

sep还支持正则表达式,这是很多老手都在用但新手不知道的细节。比如有的文件里分隔符不规律,有时是逗号有时是多个空格,用sep=r'[,;|]+'就能把连续的逗号分号竖线任意组合都当成一个分隔符处理。

另外一个容易被忽略的参数是delimiter,它和sep其实是同一个东西,写谁都行,但注意不要同时写两个,会报参数冲突。还有个delim_whitespace=True,等价于sep=r'\s+',是处理空格分隔文件的速记写法,在日志类数据上很常用。

遇到分隔符极其混乱的文件,我习惯先不急着读完整,而是nrows=5只读前五行看看效果,确认列数、列名、字段值都正常了,再放开读全量。这一招能少踩很多坑。

2.3 用dtype和parse_dates控制读入成本

read_csv默认会自己去推断每一列的数据类型,这听起来很方便,但推断过程有代价:对于大文件,Pandas需要额外扫描数据才能决定某个列到底是int64还是float64,有时还会把该是数字的列推断成object,或者把大数字转成科学计数法。两个参数能有效控制这个问题:

df = pd.read_csv('large_data.csv', dtype={ '商户ID': 'int32', '用户手机号': 'str', '金额': 'float32', '交易时间': 'str', }, parse_dates=['交易时间'])

dtype参数本质上是把类型推断的主导权从Pandas手里拿回来。你在读文件之前就知道哪一列是ID、哪一列是文本、哪一列是金额,直接告诉Pandas,省掉它的扫描过程。对大文件来说,这一项能明显缩短读入时间,同时降低内存占用,因为float32占用的内存是float64的一半。

parse_dates的用处是把日期字符串直接转成datetime64类型。这么做的好处相当大:只有真正的datetime类型才能用dt.year、dt.month做时间聚合,也才能做时间排序、时间窗口筛选。如果你不在读入时转换,后续还得再调用pd.to_datetime,浪费一趟全表扫描。

还有个实用的读入策略:

df_preview = pd.read_csv('huge.csv', nrows=1000) print(df_preview.dtypes)

先读1000行看一下类型,再正式读取时把手动指定的dtype传进去,这是一个非常高效的工作流。我每次拿到陌生的大CSV文件都会这样先探路,比盲读全量再回头排查快得多。

3. 数据清洗过程中的类型转换与字段规整

3.1 astype和pd.to_numeric的现实差异

CSV读进来之后,最常见的抱怨就是:"我这列明明是数字,怎么算不了平均?"。打开dtypes一看,那一列是object类型。这种情况多发生在文件里带了货币符号、千分位逗号、或者空格。

用astype直接硬转经常翻车:

df['金额'].astype(float) # 如果值是 '¥1,234.00',直接报错

pd.to_numeric带了个errors参数,可以让转换对脏数据更容忍:

df['金额'] = pd.to_numeric(df['金额'].str.replace('¥', '').str.replace(',', ''), errors='coerce')

用errors='coerce'时,无法转换的值会变成NaN,而不是中断整个DataFrame的处理。之后再统一填缺失值或剔除异常值即可。这套做法在处理网页爬虫导出的数据、银行账单、财务系统导出数据时几乎必用。

再补一招:如果列里混入中文数字、百分比的场景,先做替换再to_numeric:

df['增长率'] = df['增长率'].str.replace('%', '').astype(float) / 100

一个很常见的错误是链式调用写的爽,但改动没有生效——因为某些列本身是字符串类型,.str.replace返回新列,但你忘了赋值回去。整个过程记住一句话:凡是涉及列内容改变的清洗操作,都要把结果重新赋给原列,df['列名'] = df['列名'].astype(...)这种左边的赋值不能省。

3.2 日期时间列的统一格式处理

日期格式是CSV里真正让人头秃的问题。同一个文件里可能出现2024/01/01、2024-01-01、20240101、2024年1月1日这几种写法,特别是多个系统合并出来的文件。Pandas的to_datetime本身有很强的解析能力,大多数标准格式都能识别,但碰上混合格式时,最好还是先统一成字符串再做解析。

df['交易日期'] = pd.to_datetime(df['交易日期'], format='mixed', errors='coerce')

其中format='mixed'是pandas 2.x才有的参数,表示允许Pandas用推断方式处理混用格式,底层会自动选择解析策略,实测对一列里同时存在斜杠线和横杠线的情况有效。如果确认格式统一,也可以指定精确格式来加速解析:

# 只适配'YYYY/MM/DD' df['交易日期'] = pd.to_datetime(df['交易日期'], format='%Y/%m/%d')

errors='coerce'在这里同样好用,解析失败的日期变成NaT,事后可以用df[df['交易日期'].isna()]快速定位问题行。我一直建议在清洗阶段就把日期统一转成标准datetime类型,因为这个类型做时间区间筛选时表达能力比字符串强太多。

# 筛选2024年1月之后的数据 mask = df['交易日期'] >= '2024-01-01' df.loc[mask]

日期字符串之间的比较容易出各种边界问题,datetime类型则永远按时间顺序来,不会出现'2024-9-1' > '2024-10-1'这类字符串排序错误。

3.3 字符串列里的隐形空格与脏值

CSV文件里的字符串列,尤其是用户填写的字段,经常藏着肉眼看不见的首尾空格。这些空格会让groupby时同样的内容被分成两个组:"北京"和"北京 "看起来差不多,但分组统计时就是两个组。我踩过最惨的一次,是把一个四万多行的地址表做去重统计,跑完发现数量多了一倍,排查半天才看到是空格搞的鬼。

解决办法是清洗时统一调.str.strip():

df['城市'] = df['城市'].str.strip()

如果需要同时清理左右空白、统一大小写,可以连着写:

df['用户名'] = df['用户名'].str.strip().str.lower()

还有一类脏值是全角空格、不间断空格\xa0,这些在网页抓取的数据里很常见。普通的.strip()对付不了,需要用正则替换:

df['备注'] = df['备注'].str.replace(r'[\u3000\xa0]', '', regex=True)

处理完字符串列之后,我习惯用.nunique()再确认一遍分组基数是否符合预期:

print(df['城市'].nunique()) print(df['城市'].value_counts().head())

如果洗的不干净,这里一眼就暴露问题。字符串清洗这步没有太多黑魔法,核心就是把你能想到的所有空白形式全部干掉。

4. 大文件与内存极限:分块读取和降内存实战

4.1 memory_usage告诉你的内存真相

判断Pandas处理CSV时内存占多少,不要靠猜,用memory_usage看:

df.info(memory_usage='deep') df.memory_usage(deep=True)

一个容易忽略的事实:同样一份CSV,磁盘上可能只有80MB,读进DataFrame后内存轻松涨到500MB甚至更多。原因是磁盘上的字符串是紧凑存储的,而Pandas对object类型的列会把每个字符串作为独立Python对象来管理,对象头开销极大。所以优化内存的第一步,永远是看看到底哪一列在吃内存。

我刚入行时处理过一个约2GB的CSV,电脑配置一般,第一次pd.read_csv直接把内存吃满,整个进程被杀。后来用df.memory_usage(deep=True)逐列看,发现一列是用户详情的自由文本,占了一半内存。把这一列单独剔除后,剩下字段全部指定dtype,内存降到不到原来的四分之一。

4.2 chunksize分块处理与增量写回

当文件大到一次读入就会撑爆内存的时候,正确姿势是分块读取。read_csv支持chunksize参数,返回一个TextFileReader迭代器,可以逐块处理:

chunk_iter = pd.read_csv('超大文件.csv', chunksize=100000) results = [] for chunk in chunk_iter: # 对每个块做清洗或聚合 summary = chunk.groupby('类别')['金额'].sum() results.append(summary) final_result = pd.concat(results).groupby(level=0).sum() print(final_result)

分块的精髓在于"块内处理,块间合并"。每个块独立做变换,最后把块的中间结果汇总成一个final_result,这样内存里永远只同时存在一个块和一个小得多的中间结果。

如果分块处理的目标是输出另一个大CSV,可以用to_csv的mode='a'追加写,配合每个块写出时去掉表头:

chunk_iter = pd.read_csv('源数据.csv', chunksize=100000) first = True for chunk in chunk_iter: clean = chunk.dropna(subset=['关键列']) clean.to_csv('清洗后.csv', mode='a', index=False, header=first) first = False

这里header=first意味着只有第一块写出时带列名,后面的块只追加数据。这个方法在内存受限的机器上处理几GB的CSV非常顺畅,基本靠它救了我和我的老笔记本好几次。

4.3 category类型在业务数据里的奇效

category类型是pandas 2.x时代降内存效果最立竿见影的工具,尤其适合那些"只有少数几种取值但出现次数极多"的列,比如性别、省市区、订单状态、支付渠道。一个字符串列存了一万次'待支付',用object类型就要存一万个Python字符串对象;转成category后,底层只维护一个类似枚举的映射表,每行数据只存一个整数编码。

df['订单状态'] = df['订单状态'].astype('category') df['省份'] = df['省份'].astype('category')

转换之后再df.info(memory_usage='deep')看内存,往往能看到惊人的下降。我遇到过一个情况是某列从占内存25%降到只占不到2%。

category类型还有另一层价值——原来乱序的字符串分组操作,转成category之后,groupby时的排序会和category的categories顺序一致,这在业务排布、图表展示时反而能保持固定顺序,不会乱跳。比如柱状图想按"待支付、已支付、已退款"的顺序展示,提前给category指定categories顺序即可。

from pandas.api.types import CategoricalDtype order = CategoricalDtype(categories=['待支付', '已支付', '已退款'], ordered=True) df['订单状态'] = df['订单状态'].astype(order)

之后value_counts()、groupby出来的顺序都会严格按这个顺序排列,这在后面接可视化时能省去不少手工调序的麻烦。

5. 从CSV写入到更优的存储方案

5.1 to_csv的参数细节:index、encoding与columns

写完清洗好的数据,输出CSV也一样有门道。to_csv里被我用到频率最高的三个参数是index、encoding和columns。

index=False几乎是我写CSV时的肌肉记忆。默认情况下Pandas会把索引列也写出去,生成一个叫Unnamed: 0的列,别人拿到文件后总会问"这第一列哪来的"。自己用倒无所谓,交出去的CSV一定带index=False。

encoding='utf-8-sig'是给下游使用者减少困扰的输出设置。如果文件要交给同事用Excel打开,UTF-8无BOM会导致Excel直接识别成乱码,utf-8-sig因为有BOM标记,Excel能正确识别为中文UTF-8,打开就不再乱码了。

一次性只输出部分列可以用columns参数传一个列名列表,既省文件体积又避免把冗余字段交给下游:

df.to_csv('输出.csv', index=False, encoding='utf-8-sig', columns=['订单号', '金额', '交易日期'])

另外还有几个细节:sep='\t'可以输出制表符分隔的样式,方便一些特殊软件或人工贴到Excel中时自动分列;float_format='%.2f'可以控制浮点数的精度,避免写出0.30000000000000004这种难看的尾数。

5.2 压缩与切分:超过Excel上限怎么处理

Excel的CSV打开上限大约是1048576行,超过这个行数的数据文件,对方用Excel打开时会被截断,或者提示"文件格式与扩展名不匹配"。处理这类大文件,基本思路是切分输出。

按固定行数切分,随手就能写:

chunk_iter = pd.read_csv('源数据.csv', chunksize=500000) for i, chunk in enumerate(chunk_iter): chunk.to_csv(f'输出_part{i+1}.csv', index=False, encoding='utf-8-sig')

或者如果DataFrame已经整体在内存里了,直接用iloc按行切分:

n = 500000 for i in range(0, len(df), n): df.iloc[i:i+n].to_csv(f'输出_part{i//n+1}.csv', index=False, encoding='utf-8-sig')

压缩方面,to_csv支持在文件名后加.gz后缀,Pandas会自动用gzip压缩写文件:

df.to_csv('输出.csv.gz', index=False, compression='gzip')

压缩后的文件在传输时能省九成空间,读取时Pandas也能推断压缩格式直接读:

pd.read_csv('输出.csv.gz')

唯一要注意的是,压缩文件无法用Excel直接打开,但作为归档、交付给分析师用Pandas处理,这个方案又稳又省。

5.3 parquet和HDF5在什么场景才值得换

CSV是交换格式,不是存储格式。它跨软件通用、谁都能打开、Excel也能认,这就是它的最大价值。但它也有明显短板:没有类型信息,所有的类型推断都要靠每次重新扫描文件内容;文件体积大,重复数据压缩率低;不支持随机切片读取。

当我需要反复使用同一份中间结果、且性能要求高时,我会把数据转存成parquet格式:

df.to_parquet('处理结果.parquet', index=False)

再次读取时类型信息完整保留,pd.read_parquet的速度比同等体量CSV快好几倍,而且文件通常小很多。同样一个五六百万行的数据集,CSV可能两百多MB,parquet压缩后三四十MB,读取耗时也会从十几秒降到两三秒。

另一种老牌选择是HDF5格式,它的优势是在一个文件里可以存多份数据集、支持按键访问:

df.to_hdf('存储.h5', key='order_table', mode='w') pd.read_hdf('存储.h5', key='order_table')

HDF5适合需要持久化的DataFrame,写入读取速度也快,但它对字符串支持的效率不如parquet,而且依赖PyTables库,装起来比pyarrow稍麻烦一点。我自己的选型规律是:

场景推荐格式原因
给外部系统/同事交换数据CSV通用性最好,任何人可打开
中间结果要反复读parquet类型保留、体积小、读取快
同一文件存多份结构化数据HDF5文件内按键访问,按需读取
长期归档大数据parquet.gz压缩率高且保留类型
给Excel重新导入CSV utf-8-sig不会乱码,行数低于104W才建议

如果是规范CSV文件,还可以顺手加上schema校验:读进来后用assert检查列是否存在、dtypes是否符合预期。这步能帮我提前发现上游系统悄悄改了字段名或字段类型的问题。

6. 实战链路:从足球数据到GIS平台的属性表处理

6.1 football-data.co.uk的赔率CSV解析思路

经常玩数据建模的人可能见过football-data.co.uk这个站点,上面有大量足球联赛的赛果、赔率历史数据,直接以CSV形式提供下载。这类公开数据集的CSV解析和业务内网的表格逻辑一致,但有几个细节非常典型。

首先是列名里包含特殊字符,比如AvgH、AvgD、AvgA这类缩写,毫无可读性。读入之后我一般会重新命名:

df = pd.read_csv('football_data.csv', encoding='utf-8-sig') df.columns = ['比赛日期', '主队', '客队', '主队进球', '客队进球', ...]

其次是像这类数据里经常会有部分行的某些字段为空,尤其是赛季末尾或者停赛调整的行。处理时不要删整行,而是确认哪一列对业务建模最关键再决定。比如建模用历史赔率做输入,那么赔率列的空值肯定要剔除掉;但如果只是统计胜负分布,进球列没有缺失,就保留全表。

另一个常被忽略的点是日期格式,这类网站通常使用DD/MM/YYYY,而to_datetime默认按YYYY-MM-DD处理更容易出错,所以一定要显式指定format或者先替换:

df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y', errors='coerce')

这类公开CSV在Kaggle、GitHub等渠道经常有人二次加工,读入前最好都看一眼前几行的列名类型,避免走上"先读再猜,猜错再返工"的弯路。

6.2 ArcGIS/Pro这类GIS软件里的CSV导入与pandas配合

Arcgis以及Arcgis Pro这类GIS软件里导入CSV也是热搜高位问题。很多人以为GIS软件对CSV的导入是"一键操作",实际上CSV里有经纬度列、坐标参考系不规范、属性列带中文编码问题时,导入结果往往出现点位置全错或者属性表乱码,根本原因是CSV本身没有携带坐标参考系信息,软件只能盲猜。

我自己的处理流程是:先用Pandas把CSV清洗好,再导进GIS软件。清洗的重点包括:

  • 确认经纬度列名能被GIS识别。ArcGIS通常认X、Y或Longitude、Latitude这类固定字段名,如果CSV里写的是经度、纬度,可以先重命名。
  • 把经纬度列转换为统一的float64类型,去掉°符号、方向缩写之类的干扰内容。
  • 明确坐标参考系是WGS84还是GCJ-02等,这一步直接关系到点会不会偏到海里。Pandas处理不了坐标参考系,但能保证进入GIS前的字段干净。

ArcGIS Pro本身也内置了Python环境,可以安装pandas。在Pro的Python环境中用conda装pandas时,注意不要直接替换ArcGIS自带的环境,应该新建克隆环境再装,否则可能破坏ArcGIS的包依赖。

回到CSV本身,即便不导入GIS,我们也可以用Pandas自带的聚合能力分析CSV中的空间属性,比如按城市聚合统计、按经纬度网格分桶。这样处理底表时就能避开GIS软件里大文件拖拽卡顿的问题。

6.3 数据可视化联动:清洗后的CSV如何喂给matplotlib

Pandas处理完CSV,最终往往要落到图上。pandas与matplotlib练习这个热搜词说明很多人卡在"数据处理完,却不知道如何画图"。

其实链路特别顺:DataFrame可以直接作为matplotlib的数据源,df.plot()是最快捷的入口。因为matplotlib本身不认CSV,它认的是数组和DataFrame。所以整个流程天然地分成了"Pandas管清洗、matplotlib管呈现"两段。

import matplotlib.pyplot as plt df['月度销售额'] = df.groupby(df['交易日期'].dt.to_period('M'))['金额'].sum() df['月度销售额'].plot(kind='bar') plt.title('月度销售额趋势') plt.show()

一个很常见的坑是中文显示:matplotlib默认字体不含中文,图表上的中文标题会变成方框。解决方式,建议先加载支持中文的字体:

plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei'] # 黑体或微软雅黑 plt.rcParams['axes.unicode_minus'] = False # 防止负号显示异常

画图之前还有一个值得做的动作:确保x轴的类型正确。时间序列聚合的索引最好转成时间格式,否则x轴的顺序和刻度标签会乱。用pd.to_datetime统一过一遍再画,比直接拿字符串日期画要顺得多。可视化这一步不需要画多复杂,柱状图、折线图、直方图基本就能覆盖日常汇报的八成需求。Pandas的绘图本质上是matplotlib的一个封装,底层对象可以混用,后续要精细化调整,直接调用plt的API即可。

7. 最后聊几句长期实战里沉淀下来的习惯

处理CSV到现在,我最深的体会是:CSV文件的坑很少来自pandas本身,多数来自对文件结构、编码、类型和存储目标的理解不够。一个真正高效的处理流程,往往不是写一段漂亮的链式代码,而是在读入之前已经确认了编码、分隔符、列类型、目标存储格式这四个关键变量。

这也是我写这篇文章的初衷——从搜索引擎的热搜词能看出来,大家最困惑的其实就集中在安装源报错、读入乱码、类型转换失败、大文件内存不足、GIS或可视化联动这五个方向。每个方向我都给出了实际跑过的解决方案,代码也都在我自己的日常脚本里重复用了很久。读者如果在公司或者自己的项目里遇到相同报错,直接照抄对应的段落基本就能解决问题。

如果后面有精力,我打算在此基础上再写一篇关于Pandas处理千万级CSV时的并行化方案,pandas.read_csv配合dask或modin的分片策略和普通分块不太一样。这次先到这里,有任何想法欢迎在评论区交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 19:53:42

基于Spring Boot的格子铺管理系统设计与实现

1. 项目概述与核心需求拆解 格子铺管理系统,说白了就是把一个物理空间切分成几十上百个独立编号的小格子,然后租给不同的商家或个人售卖自己的商品。我当年做毕业设计的时候,导师给的题目方向是“基于Spring Boot的中小规模商铺管理系统”&am…

作者头像 李华
网站建设 2026/10/6 19:51:28

Java后端+多端适配的培训机构排课系统:从数据库设计到并发预约实战

做教练培训机构的排课系统,我前后接过好几个,最典型的一个需求就是“JAVA后端 小程序 公众号 H5”全端覆盖。这类系统真正要解决的,不是写代码的问题,而是把“教练时间”“教室资源”“学员约课”“上课通知”这一整条业务链理…

作者头像 李华
网站建设 2026/10/6 19:49:40

从创客运动到氛围编程:AI编程热浪下的历史重演

1. 两个画面之间隔了十年,剧本却几乎一模一样2013年深秋,创客运动正处在最带感的年份。我第一次站在某地的创客空间展台前,有人用Arduino做了一盏跟着音乐节奏闪光的灯,有人用3D打印机打了一堆恐龙骨架,还有人把树莓派…

作者头像 李华
网站建设 2026/10/6 19:49:26

算法刷题如何反复品味:动态规划、图论与数据结构深度解析

1. 什么样的题才配得上“反复品味”四个字 我在AcWing上刷题也有一段时间了,从基础语法题一路做到提高课,最大的感受是:有些题,你AC了就觉得自己会了,可隔两周回头再看,发现当时的解法漏洞百出;…

作者头像 李华
网站建设 2026/10/6 19:48:22

信息学奥赛全解析:NOIP、NOI、IOI赛制、难度与升学价值

01 从零认识信息学奥赛:NOIP、NOI、IOI到底在比什么如果你家里有正在学编程的初中生或高中生,或者你自己就是那个每天晚上对着屏幕调代码的人,那“NOIP”“NOI”“IOI”这三个缩写大概率不会陌生。但真正能把它们之间的关系、区别、含金量讲清…

作者头像 李华
网站建设 2026/10/6 19:48:06

OpenShell怎么用?从经典开始菜单到效率增强的完整配置指南

熟悉老Windows那套交互的人,多半都听过OpenShell的大名。简单讲,这是一个开源的Windows Shell增强工具,前身是Classic Shell,作者把源码交给社区后,项目改名Open-Shell,一直维护到今天,Windows …

作者头像 李华