【问题标题】:How to convert list of dictionaries to NumPy recarray (access fields by name)如何将字典列表转换为 NumPy recarray(按名称访问字段)
【发布时间】:2021-07-02 16:09:08
【问题描述】:

我注意到可以使用点符号访问 Nd Array items Container 中的变量。

对于由 scipy 的 loadmat 包生成的文件尤其如此。

例如,以下是来自 Nd Array items Container 的变量,使用 dot 表示法访问。

dot_notation_output=stru[0].fieldA

我很好奇如何为给定的嵌套字典重现类似的东西,如下所示。

struc=[{'fieldA': 11.02, 'fieldB': 2.69,'fieldC': 2.69}, {"fieldA": 21.4, "fieldB": 66.69,'fieldC': 2.69},
           {"fieldA": 100,"fieldB": 200,'fieldC': 2.69}]

直接从 np.array 创建不会重现上面的发现

np.array(struc)

Matlab 中的结构如下创建

for idx = 1:3
    stru(idx) = create_Structure();
    stru(idx).fieldA = '1';
    stru(idx).fieldB = 3;
    stru(idx).fieldC = 44;

end

save('struc_mat.mat','stru')
    function s = create_Structure()
        %% Create a structure 
        s = struct( ...
            'fieldA', NaN,'fieldB', NaN,'fieldC',NaN);
    end

matlab生成的struc,可以用scipy-loadmat在Python中打开

from scipy.io import loadmat
stru = loadmat ( 'struc_mat.mat', squeeze_me=True, struct_as_record=False )
stru = stru['stru']
dot_notation_output=stru[0].fieldA

【问题讨论】:

  • loadmat 给你的是recarray。这是structured array 的变体,其中fields 可以访问dict 之类的,例如arr['fieldA'] 或作为属性 arr.fieldAnumpy.org/doc/stable/user/basics.rec.html。这个 recarray 子类是 numpy 历史早期引入的一种便利,但大部分被结构化数组方法所取代。

标签: python numpy matlab


【解决方案1】:

一旦您知道如何定义记录数组,从字典创建记录数组的过程就相对简单了。

  • 首先,您必须获取字典键(用作字段名称)。
  • 使用这些来定义recarray 的“dtype”。 (注意:您还需要定义每个字段“dtype”。我假设为浮点数。您可以添加逻辑来检查字典值类型以确保使用适当的类型。)
  • 使用 dtype 创建一个空的recarray。
  • 最后,遍历字典(再次)以根据字段名称和列表位置(用作数组索引)填充数组。

注意,您可以通过 2 种方式引用数组值:1) 使用您描述的点表示法:recarr[0].fieldA,或 2) 使用名称作为数组索引:recarr[0]['fieldA']。我更喜欢第二种方法,因为它提供了一种在字段名称是变量而不是硬编码时访问值的编程方式。

使用以下数据创建重新数组的代码:

import numpy as np

struc=[{'fieldA': 11.02,'fieldB': 2.69, 'fieldC': 2.69}, 
       {'fieldA': 21.4, 'fieldB': 66.69,'fieldC': 2.69},
       {'fieldA': 100,  'fieldB': 200,  'fieldC': 2.69}]

keys = []
for d in struc:
    for k in d.keys():
        if k not in keys:
            keys.append(k)

dt = np.dtype([ (name,float) for name in keys ])
recarr = np.recarray((len(struc),),dtype=dt)
print(recarr.dtype)    

for i, d in enumerate(struc):
    for key,val in d.items():
        recarr[i][key] = val

print(recarr)

    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-22
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 2017-04-23
    相关资源
    最近更新 更多