<p>如果数据以元组列表的形式开始,则创建结构化数组是直接的:</p>
<pre><code>In [228]: alist = [("Hello",2.5,3),("World",3.6,2)]
In [229]: dt = [("Col1","S8"),("Col2","f8"),("Col3","i8")]
In [230]: np.array(alist, dtype=dt)
Out[230]:
array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)],
dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')])
</code></pre>
<p>这里的复杂情况是,元组列表已转换为二维字符串数组:</p>
<pre><code>In [231]: arr = np.array(alist)
In [232]: arr
Out[232]:
array([['Hello', '2.5', '3'],
['World', '3.6', '2']],
dtype='<U5')
</code></pre>
<p>我们可以使用众所周知的<code>zip*</code>方法来“转置”这个数组-实际上我们需要一个双转置:</p>
<pre><code>In [234]: list(zip(*arr.T))
Out[234]: [('Hello', '2.5', '3'), ('World', '3.6', '2')]
</code></pre>
<p><code>zip</code>已经方便地给了我们一个元组列表。现在我们可以用所需的数据类型重新创建数组:</p>
<pre><code>In [235]: np.array(_, dtype=dt)
Out[235]:
array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)],
dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')])
</code></pre>
<p>接受的答案使用<code>fromarrays</code>:</p>
<pre><code>In [236]: np.rec.fromarrays(arr.T, dtype=dt)
Out[236]:
rec.array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)],
dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')])
</code></pre>
<p>在内部,<code>fromarrays</code>采用一种常见的方法:创建目标数组,并按字段名复制值。有效地:</p>
<pre><code>In [237]: newarr = np.empty(arr.shape[0], dtype=dt)
In [238]: for n, v in zip(newarr.dtype.names, arr.T):
...: newarr[n] = v
...:
In [239]: newarr
Out[239]:
array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)],
dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')])
</code></pre>