在Python 2.7.3中为numpy数组分配字段名

在Python 2.7.3中为numpy数组分配字段名,python,arrays,python-2.7,numpy,user-defined-types,Python,Arrays,Python 2.7,Numpy,User Defined Types,我对这一点非常着迷,因为我显然没有抓住要点,解决方案太简单了,看不出来:( 我有一个包含x列的np.array,我想分配一个字段名。下面是我的代码: data = np.array([[1,2,3], [4.0,5.0,6.0], [11,12,12.3]]) a = np.array(data, dtype= {'names': ['1st', '2nd', '3rd'], 'formats':['f8','f8', 'f8']}) print a['1st'] 为什么会这样 [[ 1.

我对这一点非常着迷,因为我显然没有抓住要点,解决方案太简单了,看不出来:(

我有一个包含x列的np.array,我想分配一个字段名。下面是我的代码:

data = np.array([[1,2,3], [4.0,5.0,6.0], [11,12,12.3]])
a = np.array(data, dtype= {'names': ['1st', '2nd', '3rd'], 'formats':['f8','f8', 'f8']})
print a['1st']
为什么会这样

[[  1.    2.    3. ]
 [  4.    5.    6. ]
 [ 11.   12.   12.3]]
而不是
[1,2,3]

In [1]: data = np.array([[1,2,3], [4.0,5.0,6.0], [11,12,12.3]])
In [2]: dt = np.dtype({'names': ['1st', '2nd', '3rd'], 'formats':['f8','f8', 'f8']})
您的尝试:

In [3]: np.array(data,dt)
Out[3]: 
array([[(1.0, 1.0, 1.0), (2.0, 2.0, 2.0), (3.0, 3.0, 3.0)],
       [(4.0, 4.0, 4.0), (5.0, 5.0, 5.0), (6.0, 6.0, 6.0)],
       [(11.0, 11.0, 11.0), (12.0, 12.0, 12.0), (12.3, 12.3, 12.3)]], 
      dtype=[('1st', '<f8'), ('2nd', '<f8'), ('3rd', '<f8')])
我应该注意的是,只有当所有字段都与原始字段具有相同的数据类型时,
view
才有效。它使用相同的数据缓冲区,只是对值的解释不同而已

您可以将结果从(3,1)重塑为(3,)

但是,既然您希望
A['1st']
成为
[1,2,3]
-一行
数据
,我们就必须进行一些其他操作

In [16]: data.T.copy().view(dt)
Out[16]: 
array([[(1.0, 4.0, 11.0)],
       [(2.0, 5.0, 12.0)],
       [(3.0, 6.0, 12.3)]], 
      dtype=[('1st', '<f8'), ('2nd', '<f8'), ('3rd', '<f8')])
In [17]: _['1st']
Out[17]: 
array([[ 1.],
       [ 2.],
       [ 3.]])
这是一个包含3个字段的(3,)数组

元组列表是将数据提供给
np.array(…,dt)
的正常方式请参见我评论中的doc链接

您还可以创建一个空数组,并逐行或逐字段填充它

没有
复制
我会得到一个
值错误:ndarray不是C-连续的

按字段填写:

In [29]: for i in range(3):
   ....:     A[dt.names[i]]=data[i,:]
通常,结构化数组有许多行和几个字段。因此按字段填充相对较快。这就是
recarray
函数处理大多数复制任务的方式


也可以使用来自ITER的

In [31]: np.fromiter(data, dtype=dt)
Out[31]: 
array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0), (11.0, 12.0, 12.3)], 
     dtype=[('1st', '<f8'), ('2nd', '<f8'), ('3rd', '<f8')])
zip(*data)
是对输入数组重新排序的另一种方法(请参见注释链接中的
@unutbu的回答)

正如一篇评论中指出的,
fromarrays
有效:

np.rec.fromarrays(data,dt)
这是使用
by field
复制方法的
rec
函数的一个示例:

arrayList = [sb.asarray(x) for x in arrayList]
....
_array = recarray(shape, descr)
# populate the record array (makes a copy)
for i in range(len(arrayList)):
    _array[_names[i]] = arrayList[i]
在我们的案例中是:

In [8]: data1 = [np.asarray(i) for i in data]
In [9]: data1
Out[9]: [array([ 1.,  2.,  3.]), array([ 4.,  5.,  6.]), array([ 11. ,  12. ,  12.3])]
In [10]: for i in range(3):
    A[dt.names[i]] = data1[i]

我不能告诉你为什么这不起作用,但是一个解决方案是使用
np.rec.fromarray
代替:
a=np.rec.fromarray(数据,dtype={'names':['1st','2nd','3rd'],'formats':['f8','f8','f8']})
。这使得这个问题本质上是重复的。是的。那太完美了!仍然想知道为什么我的示例不起作用。请更正您的示例中的
fromarray
->
fromarys
。非常感谢!这个答案可能会有所帮助,基本上您似乎无法用numpy命名行,但您可以使用列名设置结构化数组s、 ..
数据
需要是
元组的列表
In [32]: np.fromiter(data.T, dtype=dt)
  ValueError: ndarray is not C-contiguous
np.fromiter(zip(*data),dtype=dt)
np.rec.fromarrays(data,dt)
arrayList = [sb.asarray(x) for x in arrayList]
....
_array = recarray(shape, descr)
# populate the record array (makes a copy)
for i in range(len(arrayList)):
    _array[_names[i]] = arrayList[i]
In [8]: data1 = [np.asarray(i) for i in data]
In [9]: data1
Out[9]: [array([ 1.,  2.,  3.]), array([ 4.,  5.,  6.]), array([ 11. ,  12. ,  12.3])]
In [10]: for i in range(3):
    A[dt.names[i]] = data1[i]