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

将C生成的嵌套numpy ndarray转为一维数组并保留dtype生成DataFrame

问题

需要解析一个.npy格式的输出文件,其中是附带dtype的嵌套ndarray。目标是将该数组“展开”并最终转换为结构规整的pandas DataFrame,同时尽可能保留指定的dtype。

导入的数据片段如下:

array([([(0,    11371952, [nan, nan, nan], [nan, nan, nan], 0, 0, nan, nan, 4096, -3.05175781e-05, nan, [2.51214953e-07, 2.51214953e-07, 2.51214953e-07], 2.23795245e-06, 2.37582674e-06, 0., 0., 0., 0., 0., 0.,    0.        ), (1,    11508720, [nan, nan, nan], [nan, nan, nan], 0, 0, nan, nan, 4096, -3.05175781e-05, nan, [2.51214953e-07, 2.51214953e-07, 2.51214953e-07], 2.23795245e-06, 2.37582674e-06, 0., 0., 0., 0., 0., 0.,    0.        )], 0,  0, 2.87718000e-01,      0, False, False, 255, 0),
      ...
       ([(0, 50474899154, [nan, nan, nan], [nan, nan, nan], 0, 0, nan, nan, 4096, -3.05175781e-05, nan, [2.51214953e-07, 2.51214953e-07, 2.51214953e-07], 2.63046954e-06, 2.51181307e-06, 0., 0., 0., 0., 0., 0.,    0.        ), (1, 50475035925, [nan, nan, nan], [nan, nan, nan], 0, 0, nan, nan, 4096, -3.05175781e-05, nan, [2.51214953e-07, 2.51214953e-07, 2.51214953e-07], 2.63046954e-06, 2.51181307e-06, 0., 0., 0., 0., 0., 0.,  500.06250781)], 0, 11, 1.26187590e+03, 133155, False, False, 255, 0)],
      dtype=[('itr', [('itr', '<i4'), ('tic', '<u8'), ('loc', '<f8', (3,)), ('lnc', '<f8', (3,)), ('eco', '<i4'), ('ecc', '<i4'), ('efo', '<f8'), ('efc', '<f8'), ('sta', '<i4'), ('cfr', '<f8'), ('dcr', '<f8'), ('ext', '<f8', (3,)), ('gvy', '<f8'), ('gvx', '<f8'), ('eoy', '<f8'), ('eox', '<f8'), ('dmz', '<f8'), ('lcy', '<f8'), ('lcx', '<f8'), ('lcz', '<f8'), ('fbg', '<f8')], (2,)), ('sqi', '<u4'), ('gri', '<u4'), ('tim', '<f8'), ('tid', '<i4'), ('vld', '?'), ('act', '?'), ('dos', '<i4'), ('sky', '<i4')])

期望输出的DataFrame包含62列,如itr、tic、locX、locY、locZ、lncX、lncY、lncZ、eco、ecc等。

尝试过以下代码展开数组,但处理后的数据无法保留原dtype,注释的参数也无法正常工作:

from numpy.lib import recfunctions as rfn
unstdata = rfn.structured_to_unstructured(data) #dtype=data.dtype
解决方案

嵌套结构化数组需要分两步展开:先拆分内层重复的字段,再展开多维数组字段,最后转换为DataFrame保留原dtype。

具体实现代码

import numpy as np
import pandas as pd
from numpy.lib import recfunctions as rfn

# 加载.npy数据
data = np.load('your_file.npy')

# 步骤1:展开内层的itr字段(长度为2的结构化数组)
# 将每个外层元素的2个itr条目拆分为独立行,同步复制其他外层字段
expanded_itr = rfn.repeat_fields(data, ['itr'], repeats=2)

# 步骤2:展开多维字段(loc、lnc、ext)为单列
def expand_multidim_fields(arr, field_name, suffixes=['X', 'Y', 'Z']):
    # 提取目标多维字段数据
    field_data = arr[field_name]
    # 拆分为多个独立列
    expanded_cols = np.column_stack([field_data[:, i] for i in range(field_data.shape[1])])
    # 生成新字段的dtype定义
    new_dtypes = [(f"{field_name}{s}", field_data.dtype) for s in suffixes]
    # 转换为结构化数组
    expanded_struct = np.core.records.fromarrays(expanded_cols.T, dtype=new_dtypes)
    # 删除原字段,合并新字段
    return rfn.merge_arrays([rfn.drop_fields(arr, field_name), expanded_struct], flatten=True)

# 依次展开所有多维字段
expanded_data = expanded_itr
for field in ['loc', 'lnc', 'ext']:
    expanded_data = expand_multidim_fields(expanded_data, field)

# 步骤3:转换为DataFrame并保留原dtype
df = pd.DataFrame(expanded_data)

# 验证结果
print(f"总列数:{len(df.columns)}")
print(df.dtypes)

关键说明

  • rfn.repeat_fields:专门用于拆分结构化数组中重复的子字段,确保每个itr条目对应一行,同时保留其他字段的对应值。
  • expand_multidim_fields:将三维数组字段拆分为locX、locY等单列,严格保留原字段的dtype。
  • 最终转换为DataFrame时,pandas会直接继承结构化数组的dtype,无需额外处理即可保留原类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:27:52