如何展平numpy结构化数组的嵌套字段并转换为pandas DataFrame
通用实现方案
方案1:基于Numpy原生工具实现(性能最优)
利用numpy.lib.recfunctions的内置工具自动处理结构化数组的dtype展平,自动适配所有第一层的多值字段,不需要手动处理字段偏移:
import numpy as np import pandas as pd from numpy.lib import recfunctions as rfn def flatten_struct_to_df(arr: np.ndarray) -> pd.DataFrame: # 自动解析所有字段的元信息 new_dtype = [] for field_name, field_dtype in arr.dtype.fields.items(): dt, *shape = field_dtype if shape: # 多值字段拆分生成多个单列 dim = shape[0][0] if isinstance(shape[0], tuple) else shape[0] for idx in range(dim): new_dtype.append((f"{field_name}_{idx}", dt)) else: # 单值字段直接保留 new_dtype.append((field_name, dt)) # 转换为展平后的结构化数组 flat_arr = rfn.repack_fields(arr.view(new_dtype)) # 直接生成DataFrame return pd.DataFrame(flat_arr)
调用示例:
data = np.array( [((1,2,3), True), ((4,5,6), False)], dtype=[("nums", ('u4', 3)), ("v", "?")] ) df = flatten_struct_to_df(data) print(df)
输出结果:
nums_0 nums_1 nums_2 v 0 1 2 3 True 1 4 5 6 False
方案2:轻量遍历实现(无额外依赖)
不需要导入recfunctions模块,直接遍历字段生成DataFrame,逻辑简单易修改:
def flatten_struct_to_df_v2(arr: np.ndarray) -> pd.DataFrame: res = {} for field in arr.dtype.names: val = arr[field] if len(val.shape) > 1: # 拆分多值字段为多列 for i in range(val.shape[1]): res[f"{field}_{i}"] = val[:, i] else: res[field] = val return pd.DataFrame(res)
方案优势
- 完全自动适配任意schema,不需要手动指定字段名,支持任意数量的第一层多值嵌套列
- 底层基于Numpy原生向量运算实现,百万行级数据处理速度快,内存占用低
- 自动处理字段偏移逻辑,不需要手动解析dtype的偏移信息
内容的提问来源于stack exchange,提问作者ofo
相关产品推荐
相关产品推荐

