如何将含嵌套对象、集合的对象转换为扁平化Deedle DataFrame
原因
Frame.FromRecords 默认仅读取对象的一级基础类型属性,不会自动递归展开嵌套类的属性,也不会自动将数组类型属性展开为多行,因此会直接输出嵌套类的ToString()结果、数组的类型名,和你的预期不符。
最简实现方案
你可以先通过LINQ手动将嵌套结构扁平化、同时展开数组生成每行对应的实体,再传入Frame.FromRecords生成DataFrame,代码逻辑清晰易懂,适合新手使用:
SomeObject someObject = GetDeserialisedJson(); // 遍历数组元素,每个元素对应最终DataFrame的一行,合并所有层级的属性到同一对象 var flattenRecords = someObject.SomeAnotherObjectArr.Select(arrItem => new { someObject.Id, someObject.Name, // 拉平嵌套对象的属性 OtherObjectName = someObject.SomeOtherObject?.OtherObjectName, arrItem.AnotherObjectName, arrItem.Flag }); var df = Frame.FromRecords(flattenRecords); df.Print();
注意:代码中使用了空值传播运算符
?,可以避免SomeOtherObject为null时触发空引用异常,你可以根据实际业务情况决定是否保留。
多根对象场景适配
如果你反序列化得到的是SomeObject的集合(比如JSON根节点是数组),可以改用SelectMany实现多层展开:
List<SomeObject> objList = GetDeserialisedJsonList(); var flattenRecords = objList.SelectMany(rootObj => rootObj.SomeAnotherObjectArr.Select(arrItem => new { rootObj.Id, rootObj.Name, OtherObjectName = rootObj.SomeOtherObject?.OtherObjectName, arrItem.AnotherObjectName, arrItem.Flag }) ); var df = Frame.FromRecords(flattenRecords);
其他可选思路
如果你的业务场景中嵌套结构经常变化,不想每次手动写匿名类,可以写通用的反射扩展方法,递归遍历对象的所有属性、展开数组生成扁平化的字典集合,再通过字典集合构造DataFrame,不过通用方法的开发和调试成本更高,性能也弱于手动指定属性的写法,非必要场景不推荐新手使用。
内容的提问来源于stack exchange,提问作者Navjot Singh
相关产品推荐
相关产品推荐

