如何用Pandas+PyArrow读取大TXT文件时通过usecols筛选数据?
解决PyArrow引擎读取大CSV时
usecols参数触发类型错误的问题 手上有一个无表头、空格分隔的7列浮点型大TXT文件,为提升读取速度采用PyArrow引擎并行读取,但使用usecols=[0,1,2]筛选前3列时触发错误:
TypeError: expected bytes, int found
环境:Ubuntu 20.04.5 LTS、Python 3.8.10、Pandas 2.0.1、PyArrow 12.0.0
问题原因
Pandas 2.0.x搭配PyArrow引擎时,usecols参数不支持直接传入整数索引。PyArrow引擎需要接收列名字符串而非位置索引——因为代码中已经通过names参数指定了列名(["0","1","2","3","4","5","6"]),传入整数索引会导致类型不匹配。
解决方案
方案1:修改usecols为列名字符串列表
直接使用定义好的列名字符串指定需要读取的列,代码如下:
import pandas as pd import numpy as np names = [str(i) for i in range(7)] pointcloud = pd.read_csv( pointcloud_file, index_col=None, dtype=np.float16, names=names, header=None, sep=" ", engine="pyarrow", usecols=["0", "1", "2"], # 改为列名字符串 ).to_numpy(dtype=np.float16)
该方案让PyArrow引擎正确识别目标列,读取阶段仅加载前3列,避免全量读取占用过多内存,同时保留并行读取的效率。
方案2:直接使用PyArrow原生API(更高效)
若追求极致内存效率与并行性能,可直接使用PyArrow原生CSV读取接口,支持更精细的控制:
import pyarrow.csv as pv import pyarrow as pa import numpy as np # 配置读取选项 convert_options = pv.ConvertOptions( include_columns=["0", "1", "2"], # 指定要加载的列名 column_types={ "0": pa.float16(), "1": pa.float16(), "2": pa.float16() } ) read_options = pv.ReadOptions( skip_rows=0, column_names=[str(i) for i in range(7)] # 指定列名 ) parse_options = pv.ParseOptions( delimiter=" " # 指定分隔符为空格 ) # 读取文件并转为numpy数组 table = pv.read_csv( pointcloud_file, read_options=read_options, parse_options=parse_options, convert_options=convert_options ) pointcloud = table.to_pandas().to_numpy(dtype=np.float16)
PyArrow原生API会在读取阶段直接过滤掉不需要的列,内存占用更低,并行处理效率也更高,适合超大文件场景。
验证
两种方案均实现读取时仅加载目标列,无需全量读取后再截取,完美解决内存限制问题,同时保留PyArrow的并行读取优势。
内容的提问来源于stack exchange,提问作者Thompsoncikl
相关产品推荐
相关产品推荐

