我必须以某种方式将结构化数据转换为numpy结构化数组形式。我读了一篇关于这个我能找到的主题的小问题和(抱歉的SciPy!)草率文档,但仍然无处可去。
基本上我想做一些像这样简单的事情:
import numpy as np
dt = [('contacts', '(2,4)f8'),
('modelname', 'S10')]
arr = np.zeros((2,), dtype=dt)
testdata = [[99, 2, 3, 4], [7, 8, 9, 10]]
arr[0]['contacts'] = np.array(testdata)
arr[0]['modelname'] = 'test'
print arr
然后我想看看该领域的联系人'要将结构化数组设置为所需内容。
然而,输出是:
[([[99.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]], 'test')
([[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]], '')]
显然只分配了第一个号码。
答案 0 :(得分:3)
你正在以错误的方式索引你的数组。尝试:
arr['contacts'][0] = np.array(testdata)
也就是说,对于'contacts'
的{{1}}列,请将arr
索引的行设置为0
。当你写testdata
时,你会检索一个“记录标量”。实际上,如果您检查,则会看到arr[0]
的类型为arr[0]
。
分配给它不会影响分配给整个记录的内存。相比之下,numpy.void
创建视图并在该数组视图中分配给arr['contacts']
修改原始内存。
我同意NumPy文档可以更清楚......
答案 1 :(得分:-1)
你的作业只改变了第一个数字这个事实对我来说很麻烦,而不仅仅是文档的问题。
In [1496]: x = np.zeros((2,),dtype=('(2,3)i4,a4'))
In [1497]: x
Out[1497]:
array([([[0, 0, 0], [0, 0, 0]], b''), ([[0, 0, 0], [0, 0, 0]], b'')],
dtype=[('f0', '<i4', (2, 3)), ('f1', 'S4')])
Buggy案例,它只分配第一个数字:
In [1498]: x[0]['f0'] = np.arange(1,7).reshape(2,3)
In [1499]: x
Out[1499]:
array([([[1, 0, 0], [0, 0, 0]], b''), ([[0, 0, 0], [0, 0, 0]], b'')],
dtype=[('f0', '<i4', (2, 3)), ('f1', 'S4')])
但添加[:]
会更正 - 它意味着'只替换数据内容'
In [1500]: x[0]['f0'][:] = np.arange(1,7).reshape(2,3)
In [1501]: x
Out[1501]:
array([([[1, 2, 3], [4, 5, 6]], b''), ([[0, 0, 0], [0, 0, 0]], b'')],
dtype=[('f0', '<i4', (2, 3)), ('f1', 'S4')])
使用元组设置整个元素 - 这在文档中有描述。元组列表设置了多个元素。
In [1502]: x[0] = (np.arange(2,8).reshape(2,3),'test')
In [1503]: x
Out[1503]:
array([([[2, 3, 4], [5, 6, 7]], b'test'), ([[0, 0, 0], [0, 0, 0]], b'')],
dtype=[('f0', '<i4', (2, 3)), ('f1', 'S4')])
首先选择该字段也是有效的(进一步证明你的案例是一个numpy bug)
In [1504]: x['f0'][0] = np.arange(3,9).reshape(2,3)
In [1505]: x
Out[1505]:
array([([[3, 4, 5], [6, 7, 8]], b'test'), ([[0, 0, 0], [0, 0, 0]], b'')],
dtype=[('f0', '<i4', (2, 3)), ('f1', 'S4')])
我对'记录标量'的解释不满意。 x
,x['f0']
和x['f0']
都有相同的__array_interface__
数据指针。
x['f0'][0]
和x[0]['f0']
具有相同的__array_interface_-
和type
。两者都适用于+=
等操作。我能找到的唯一区别在于直接阵列分配。修改数组中只有一个元素是完全错误的。
通过切片选择行也可以正常工作:
x[:1]['f0'] = ...
看起来这是相关的错误问题