【发布时间】: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]
尽管如此,所有这些解决方案都相当草率且不通用。
仍在等待语法歧义解释的正确答案。
【问题讨论】: