【问题标题】:Replacing a field of a structured Numpy array替换结构化 Numpy 数组的字段
【发布时间】:2015-08-26 09:39:58
【问题描述】:

我已经构建了分支(即某些字段包含子字段)数据类型dtype 的 numpy 数组,如下所示:

import numpy
dtype_sub = [('sub0', 'i4'), ('sub1', 'f8')]
dtype = [('info', [('field0', dtype_sub, 3),
                  ('field1', dtype_sub, 3)])]
array = [(tuple([[(0, 0.0) for j in range(3)] for i in range(2)]),)]
narray = numpy.array(array, dtype = dtype)

在生成和访问所有字段期间一切正常。 然后我尝试用新值替换其中一个字段。但是,这不起作用:

field0_new = [(1, 1.0) for i in range(3)]
print('--- Original field0: ---')
print(narray[0]['info']['field0'])
print('--- To replace with: ---')
print(field0_new)
narray[0]['info']['field0'] = field0_new
print('--- Replaced field0: ---')
print(narray[0]['info']['field0'])

输出

--- Original field0: ---
[(0, 0.0) (0, 0.0) (0, 0.0)]
--- To replace with: ---
[(1, 1.0), (1, 1.0), (1, 1.0)]
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    narray[0]['info']['field0'] = field0_new
ValueError: cannot copy sequence with size 2 to array axis with dimension 3

我有点困惑,因为替换一个更大的字段,其中包含我要替换的字段,工作正常:

info_new = [[(1, 1.0) for j in range(3)] for i in range(2)]
print('--- Original info: ---')
print(narray[0]['info'])
print('--- To replace with: ---')
print(info_new)
narray[0]['info'] = info_new
print('--- Replaced info: ---')
print(narray[0]['info'])

输出

--- Original info: ---
([(0, 0.0), (0, 0.0), (0, 0.0)], [(0, 0.0), (0, 0.0), (0, 0.0)])
--- To replace with: ---
[[(1, 1.0), (1, 1.0), (1, 1.0)], [(1, 1.0), (1, 1.0), (1, 1.0)]]
--- Replaced info: ---
([(1, 1.0), (1, 1.0), (1, 1.0)], [(1, 1.0), (1, 1.0), (1, 1.0)])

我注意到,在一种情况下,字段的打印表示中的列表内有逗号 ([(0, 0.0), (0, 0.0), (0, 0.0)]),而在另一种情况下则没有逗号 ([(0, 0.0) (0, 0.0) (0, 0.0)])。但是,我无法理解这一点,因为它们应该是同一字段的表示。

谁能帮忙解决这个问题?

编辑:

玩了一会儿后,我注意到将元组和列表传递给复杂的结构化数组有双重含义:

info_new = [[(i * j, 10.5 + j) for j in range(3)] for i in range(2)]

导致不正确

--- To replace with: ---
[[(0, 10.5), (0, 11.5), (0, 12.5)], [(0, 10.5), (1, 11.5), (2, 12.5)]]
--- Replaced info: ---
([(0, 0.0), (0, 0.0), (0, 0.0)], [(10, 10.5), (10, 10.5), (10, 10.5)])

info_new = tuple([[(i * j, 10.5 + j) for j in range(3)] for i in range(2)])

预期的输出

--- To replace with: ---
([(0, 10.5), (0, 11.5), (0, 12.5)], [(0, 10.5), (1, 11.5), (2, 12.5)])
--- Replaced info: ---
([(0, 10.5), (0, 11.5), (0, 12.5)], [(0, 10.5), (1, 11.5), (2, 12.5)])

但是,我仍然无法理解语法是如何工作的,以及为什么直接替换 field0 不起作用。

编辑 2:

目前我想出了 2 个自己的想法(加上 Warren Weckesser 的回答):

1) 将其作为更大字段的一部分传递:

info_new = tuple([field0_new, narray[0]['info']['field1']])
narray[0]['info'] = info_new

2) 分段传递:

for i in range(len(narray[0]['info']['field0'])):
    narray[0]['info']['field0'][i] = field0_new[i]

尽管如此,所有这些解决方案都相当草率且不通用。

仍在等待语法歧义解释的正确答案。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    如果你先索引字段,然后是数组序列,它会起作用:

    narray['info']['field0'][0] = field0_new
    

    (更好的答案是调查为什么,但这就是我目前得到的全部。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      相关资源
      最近更新 更多