如何在C++流式读取Parquet文件时指定读取目标列?
仅读取Parquet文件指定列的实现方法
Parquet C++官方文档给出了以下流式读取Parquet文件的示例代码:
{ std::shared_ptr<arrow::io::ReadableFile> infile; PARQUET_ASSIGN_OR_THROW( infile, arrow::io::ReadableFile::Open("test.parquet")); parquet::StreamReader stream{parquet::ParquetFileReader::Open(infile)}; std::string article; float price; uint32_t quantity; while ( !stream.eof() ) { stream >> article >> price >> quantity >> parquet::EndRow; // ... } }
若仅需读取price列,应如何实现?是否支持按列名或列号选择要读取的列?
实现方案
Parquet C++的StreamReader支持按列名或列号指定读取目标列,无需加载所有列数据,具体实现如下:
1. 按列名选择读取列
通过SelectColumns方法传入列名字符串列表,即可仅加载指定列:
{ std::shared_ptr<arrow::io::ReadableFile> infile; PARQUET_ASSIGN_OR_THROW( infile, arrow::io::ReadableFile::Open("test.parquet")); auto reader = parquet::ParquetFileReader::Open(infile); parquet::StreamReader stream{std::move(reader)}; // 仅选择"price"列 PARQUET_THROW_NOT_OK(stream.SelectColumns({"price"})); float price; while (!stream.eof()) { stream >> price >> parquet::EndRow; // 处理读取到的price数据 } }
2. 按列号选择读取列
列号从0开始计数,同样使用SelectColumns方法传入列号整数列表:
{ std::shared_ptr<arrow::io::ReadableFile> infile; PARQUET_ASSIGN_OR_THROW( infile, arrow::io::ReadableFile::Open("test.parquet")); auto reader = parquet::ParquetFileReader::Open(infile); parquet::StreamReader stream{std::move(reader)}; // 假设price是第2列(索引从0开始) PARQUET_THROW_NOT_OK(stream.SelectColumns({1})); float price; while (!stream.eof()) { stream >> price >> parquet::EndRow; // 处理读取到的price数据 } }
关键注意点
SelectColumns必须在开始读取数据前调用,一旦进入读取循环后无法修改列选择。- 如果指定的列名/列号不存在,会直接抛出错误,建议提前通过
ParquetFileReader获取文件元信息验证列的有效性。
内容的提问来源于stack exchange,提问作者roschach
相关产品推荐
相关产品推荐

