首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将numpy数组转换为结构化数组

将numpy数组转换为结构化数组
EN

Stack Overflow用户
提问于 2021-10-12 20:11:08
回答 1查看 126关注 0票数 0

假设numpy数组中行的字节宽度与dtype定义的结构中字段的总宽度相同,那么有没有一种简单的方法可以将numpy数组转换为结构化数组?

例如,my_type为所有字段中的每个数据元素定义了一个5字节的数据类型:[('checksum','u2'), ('word', 'B', (3,))]。然后,我想将numpy数组[[ 1 2 3 4 5] [ 11 12 13 14 15]]转换为结构化数组[( 258, [ 3, 4, 5]) (2828, [13, 14, 15])]

我最初的尝试是:

代码语言:javascript
运行
复制
import numpy as np
from random import randint

# generate data
array = np.array([(1,2,3,4,5), 
    (11,12,13,14,15)], dtype = np.uint8)

# format data
my_type = np.dtype([('checksum','u2'), ('word', 'B', (3,))])
structured_array = np.array([array], dtype=my_type)

但是,不出所料,由于使用了numpy broadcasting rules,我得到了以下内容:

代码语言:javascript
运行
复制
[[[( 1, [ 1,  1,  1]) ( 2, [ 2,  2,  2]) ( 3, [ 3,  3,  3])
   ( 4, [ 4,  4,  4]) ( 5, [ 5,  5,  5])]
  [( 11, [ 11,  11,  11]) (12, [12, 12, 12]) (13, [13, 13, 13])
   (14, [14, 14, 14]) (15, [15, 15, 15])]]]

我目前不太优雅的解决方案是循环遍历数组的行,并将它们映射到结构:

代码语言:javascript
运行
复制
structured_array = np.zeros(array.shape[0], dtype=my_type)
for idx, row in enumerate(array):
    for key, value in my_type.fields.items():
        b = row[value[1]:value[1]+value[0].itemsize]
        if len(structured_array[idx][key].shape):
            structured_array[idx][key] = b            
        else:
            structured_array[idx][key] = int.from_bytes(b, byteorder='big', signed=False)

因此,问题是,是否有一种简单的单行解决方案,可以对任意数据类型的结构化数组执行此任务,而无需解析numpy数组的字节?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-13 15:33:58

代码语言:javascript
运行
复制
In [222]: x = np.array([[ 0,  2,  3,  4,  5], [ 0, 12, 13, 14, 15]])
In [223]: dt = np.dtype([('checksum','u2'), ('word', 'B', (3,))])

我从过去的使用中知道,genfromtxt可以处理相对复杂的数据类型:

代码语言:javascript
运行
复制
In [224]: np.savetxt('temp', x[:,1:], fmt='%d')
In [225]: cat temp
2 3 4 5
12 13 14 15
In [226]: data = np.genfromtxt('temp', dtype=dt)
In [227]: data
Out[227]: 
array([( 2, [ 3,  4,  5]), (12, [13, 14, 15])],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])

但是我还没有深入研究它的代码,看看它是如何将平面行数据映射到数据类型的。

但事实证明,我在评论中提到的unstructured_to_structured可以处理您的dtype:

代码语言:javascript
运行
复制
In [228]: import numpy.lib.recfunctions as rf
In [229]: rf.unstructured_to_structured(x[:,1:],dtype=dt)
Out[229]: 
array([( 2, [ 3,  4,  5]), (12, [13, 14, 15])],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])

但对于更简单的dtype,我和其他人经常建议将列表列表转换为元组列表。

代码语言:javascript
运行
复制
In [230]: [tuple(row) for row in x[:,1:]]
Out[230]: [(2, 3, 4, 5), (12, 13, 14, 15)]

许多recfunctions都使用逐字段复制

代码语言:javascript
运行
复制
In [231]: res = np.zeros(2, dtype=dt)
In [232]: res
Out[232]: 
array([(0, [0, 0, 0]), (0, [0, 0, 0])],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])
In [233]: res['checksum']= x[:,1]
In [234]: res['word']
Out[234]: 
array([[0, 0, 0],
       [0, 0, 0]], dtype=uint8)
In [235]: res['word'] = x[:,2:]
In [236]: res
Out[236]: 
array([( 2, [ 3,  4,  5]), (12, [13, 14, 15])],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])

字节视图

我忽略了你想要重新打包字节的事实。我上面的答案将输入行视为4个数字/整数,它们将被分配给复合数据类型中的4个槽。但是对于uint8输入,以及u2u1插槽,您希望用新的数据类型来view这5个字节,而不是创建一个新的数组。

代码语言:javascript
运行
复制
In [332]: dt
Out[332]: dtype([('checksum', '<u2'), ('word', 'u1', (3,))])
In [333]: arr = np.array([(1,2,3,4,5),
     ...:     (11,12,13,14,15)], dtype = np.uint8)
In [334]: arr.view(dt)
Out[334]: 
array([[( 513, [ 3,  4,  5])],
       [(3083, [13, 14, 15])]],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])

view添加了一个维度,我们需要删除它:

代码语言:javascript
运行
复制
In [335]: _.shape
Out[335]: (2, 1)
In [336]: arr.view(dt).reshape(2)
Out[336]: 
array([( 513, [ 3,  4,  5]), (3083, [13, 14, 15])],
      dtype=[('checksum', '<u2'), ('word', 'u1', (3,))])

并更改u2字段的结尾:

代码语言:javascript
运行
复制
In [337]: dt = np.dtype([('checksum','>u2'), ('word', 'B', (3,))])
In [338]: arr.view(dt).reshape(2)
Out[338]: 
array([( 258, [ 3,  4,  5]), (2828, [13, 14, 15])],
      dtype=[('checksum', '>u2'), ('word', 'u1', (3,))])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69546473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档