我很担心这一点,因为我显然错过了重点,解决方案太简单了:(
我有一个带有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,3]?
最佳答案
In [1]: data = np.array([[1,12.3]])
In [2]: dt = np.dtype({'names': ['1st','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),(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','
生成一个(3,3)数组,并为每个字段分配相同的值. data.astype(dt)做同样的事情.
但是view会生成一个(3,1)数组,其中每个字段都包含一列的数据.
In [4]: data.view(dt)
Out[4]:
array([[(1.0,'
我应该提醒一下,只有当所有字段都与原始字段具有相同的数据类型时,该视图才有效.它使用相同的数据缓冲区,只是以不同的方式解释值.
您可以将结果从(3,1)重新整形为(3,).
但是既然你想要A [‘1st’]是[1,3] – 一行数据 – 我们必须做一些其他操作.
In [16]: data.T.copy().view(dt)
Out[16]:
array([[(1.0,11.0)],[(2.0,12.0)],[(3.0,'
我转置,然后复制(重新安排底层数据缓冲区).现在一个视图将[1,3]放在一个字段中.
请注意,结构化数组的显示使用()而不是[]来表示“行”.这是它如何接受输入的线索.
我可以将您的数据转换为元组列表:
In [19]: [tuple(i) for i in data.T]
Out[19]: [(1.0,12.300000000000001)]
In [20]: np.array([tuple(i) for i in data.T],dt)
Out[20]:
array([(1.0,12.3)],'
这是一个包含3个字段的(3)数组.
元组列表是向np.array(…,dt)提供数据的常规方式.请参阅我的评论中的doc链接.
您还可以创建一个空数组,逐行填充,或逐个字段填充
In [26]: A=np.zeros((3,),dt)
In [27]: for i in range(3):
....: A[i]=data[:,i].copy()
没有副本我得到一个ValueError:ndarray不是C-contiguous
按字段填写:
In [29]: for i in range(3):
....: A[dt.names[i]]=data[i,:]
通常,结构化数组有许多行和几个字段.所以按场填充相对较快.这就是重新排列函数处理大多数复制任务的方式.
fromiter也可以使用:
In [31]: np.fromiter(data,dtype=dt)
Out[31]:
array([(1.0,3.0),(4.0,6.0),(11.0,'
但是我在使用没有副本的data.T时得到的错误是一个强有力的指示,即逐行迭代(我的[27])
In [32]: np.fromiter(data.T,dtype=dt)
ValueError: ndarray is not C-contiguous
zip(* data)是重新排序输入数组的另一种方式(请参阅注释链接中的@ unutbu的答案).
np.fromiter(zip(*data),dtype=dt)
正如评论中指出的那样,fromarrays有效:
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.,3.]),array([ 4.,5.,6.]),array([ 11.,12.,12.3])]
In [10]: for i in range(3):
A[dt.names[i]] = data1[i]