You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对使用Parquet.Net读取Parquet文件得到的数组执行LINQ查询

问题根因
  1. 你当前ReadParquetFile方法返回的是Parquet.Data.DataColumn类型的数组,属于按列存储的原始数据结构,每个数组元素对应Parquet文件中的一整列数据,并非你自定义的DataFrame行对象,LINQ查询中强制类型转换必然报错。
  2. 你原有的行组遍历逻辑存在缺陷:每次遍历行组都会给allData重新赋值,最终只会保留最后一个行组的数据,前面行组的内容会全部丢失。
  3. 你的需求是按行做条件查询,必须先把列式存储的原始数据反序列化为每行对应的强类型实体,才能正常使用LINQ语法查询。
解决方法

方案1:使用Parquet.Net内置的强类型序列化(推荐)

不用手动处理列、行组逻辑,框架会自动完成列到行对象的映射:

  1. 首先定义和Parquet文件字段匹配的实体类(字段名需和Parquet字段名保持一致,类型匹配):
public class DataFrame
{
    // 字段类型根据你实际Parquet文件的字段类型调整,大数值ID推荐用long
    public long EventId { get; set; }
    public double Loss { get; set; }
    // 其余字段按Parquet文件结构补全即可
}
  1. 改写读取方法,直接读取为强类型列表:
public static List<DataFrame> ReadParquetFile(string filePath)
{
    using Stream fileStream = File.OpenRead(filePath);
    using var parquetReader = new Parquet.ParquetReader(fileStream);
    // 异步读取同步等待,也可改为异步方法
    return parquetReader.ReadAsync<DataFrame>().GetAwaiter().GetResult().ToList();
}
  1. 改写Main方法的查询逻辑:
static void Main(string[] args)
{
    var records = ReadParquetFile(@"F:\AutomationRunStation\11_12.parquet");
    
    var queryResult = from data in records
                      where data.EventId == 280000001
                      select data.Loss;

    // 遍历输出结果,直接输出queryResult只会打印集合类型名
    foreach (var lossVal in queryResult)
    {
        Console.WriteLine(lossVal);
    }
    Console.ReadKey();
}

方案2:基于现有按列读取逻辑手动映射

如果你要保留现有按列读取的写法,可以手动把多列数据按索引拼接为行对象:

static void Main(string[] args)
{
    var columns = ReadParquetFile();
    // 取出对应列的原始数据数组
    var eventIdArr = columns.First(c => c.Field.Name == "EventId").Data as long[];
    var lossArr = columns.First(c => c.Field.Name == "Loss").Data as double[];

    // 按索引拼接为DataFrame对象列表
    var records = new List<DataFrame>();
    for (int i = 0; i < eventIdArr.Length; i++)
    {
        records.Add(new DataFrame
        {
            EventId = eventIdArr[i],
            Loss = lossArr[i]
        });
    }
    
    // 后续LINQ查询逻辑和方案1一致
    var queryResult = from data in records
                      where data.EventId == 280000001
                      select data.Loss;

    foreach (var lossVal in queryResult)
    {
        Console.WriteLine(lossVal);
    }
    Console.ReadKey();
}

内容的提问来源于stack exchange,提问作者Victor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 16:45:01