构建元组数组作为元素

时间:2017-07-17 15:46:11

标签: python numpy

我有

x = np.arange(0, 4, 1)
y = np.arange(0, 4, 1)

我想要

array([[(0,0), (0,1), (0,2), (0,3)],
       [(1,0), (1,1), (1,2), (1,3)],
       [(2,0), (2,1), (2,2), (2,3)],
       [(3,0), (3,1), (3,2), (3,3)]
      ])

请注意,我希望最低级别的元组!这不是三年级的阵列!这是一个2级的数组,以元组为元素!

数字0到3只是一个例子。在实际情况下,它将是浮动的。之后,我想使用那些float-tuples作为Factory函数的参数,该函数生成用对象替换这些元组的对象。

目前问题是:我如何获得这组元组?

我调查in Numpy, how to zip two 2-D arrays?,但这不起作用,正如我的评论所揭示的那样。

3 个答案:

答案 0 :(得分:4)

array of tuples可以有多种含义。

双重迭代产生一个嵌套的元组列表:

In [292]: alist = [[(i,j) for j in y] for i in x]
In [293]: alist
Out[293]: 
[[(0, 0), (0, 1), (0, 2), (0, 3)],
 [(1, 0), (1, 1), (1, 2), (1, 3)],
 [(2, 0), (2, 1), (2, 2), (2, 3)],
 [(3, 0), (3, 1), (3, 2), (3, 3)]]

从中生成数组的默认方式会生成包含整数元素的3d数组

In [294]: arr=np.array(alist)
In [295]: arr.dtype
Out[295]: dtype('int32')
In [296]: arr.shape
Out[296]: (4, 4, 2)
In [297]: arr[0,0]
Out[297]: array([0, 0])

定义复合dtype会创建一个结构化数组:

In [298]: arr=np.array(alist,'i,i')
In [299]: arr.dtype
Out[299]: dtype([('f0', '<i4'), ('f1', '<i4')])
In [300]: arr.shape
Out[300]: (4, 4)
In [301]: arr
Out[301]: 
array([[(0, 0), (0, 1), (0, 2), (0, 3)],
       [(1, 0), (1, 1), (1, 2), (1, 3)],
       [(2, 0), (2, 1), (2, 2), (2, 3)],
       [(3, 0), (3, 1), (3, 2), (3, 3)]],
      dtype=[('f0', '<i4'), ('f1', '<i4')])

arr.tolist()看起来就像alist

此数组的元素不是元组,但它确实显示为元组。我更喜欢称之为记录。

In [303]: type(arr[0,0])
Out[303]: numpy.void
In [304]: arr[0,0]
Out[304]: (0, 0)

这些记录的2个元素是字段,可以通过名称访问,例如arr['f0'], arr['f1'],它们都是2d整数数组。

可以创建一个可以包含文字元组的对象数组(实际上指向内存中其他元组的元组:

In [305]: arr = np.empty((4,4),object)
In [306]: arr
Out[306]: 
array([[None, None, None, None],
       [None, None, None, None],
       [None, None, None, None],
       [None, None, None, None]], dtype=object)
In [307]: arr[...]=alist
In [308]: arr
Out[308]: 
array([[(0, 0), (0, 1), (0, 2), (0, 3)],
       [(1, 0), (1, 1), (1, 2), (1, 3)],
       [(2, 0), (2, 1), (2, 2), (2, 3)],
       [(3, 0), (3, 1), (3, 2), (3, 3)]], dtype=object)
In [309]: type(arr[0,0])
Out[309]: tuple

从这些x,y变量构造数组的非迭代方法是meshgrid,它返回(4,4)数组的列表。他们可以堆叠&#39;以与(4,4,2)数组相匹配的方式:

In [322]: I,J = np.meshgrid(x,y,indexing='ij')
In [323]: np.allclose(np.stack((I,J),axis=2), np.array(alist))
Out[323]: True

我们也可以从这些构造记录数组:

In [327]: arr = np.zeros((4,4),'i,i')
In [328]: arr['f0']=I
In [329]: arr['f1']=J

答案 1 :(得分:1)

选项将是。

M = np.asarray([[(i,j) for j in y] for i in x], dtype='int,int')

答案 2 :(得分:0)

https://stackoverflow.com/a/17960617/4533188的启发,似乎

xx, yy = np.meshgrid(x,y)
np.array(list(zip(yy.ravel(), xx.ravel())), dtype=('i4,i4')).reshape(xx.shape)

导致

array([[(0, 0), (0, 1), (0, 2), (0, 3)],
       [(1, 0), (1, 1), (1, 2), (1, 3)],
       [(2, 0), (2, 1), (2, 2), (2, 3)],
       [(3, 0), (3, 1), (3, 2), (3, 3)]], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])

也是一个答案。