将numpy数组转换为numpy数组的数组

时间:2015-02-02 17:57:46

标签: python arrays numpy

如何以(num)pythonic方式将numpy数组a转换为numpy数组b。理想情况下,解决方案应适用于任意维度和数组长度。

import numpy as np

a=np.arange(12).reshape(2,3,2)

b=np.empty((2,3),dtype=object)
b[0,0]=np.array([0,1])
b[0,1]=np.array([2,3])
b[0,2]=np.array([4,5])
b[1,0]=np.array([6,7])
b[1,1]=np.array([8,9])
b[1,2]=np.array([10,11])

2 个答案:

答案 0 :(得分:3)

首先:

In [638]: a=np.arange(12).reshape(2,3,2)
In [639]: b=np.empty((2,3),dtype=object)
In [640]: for index in np.ndindex(b.shape):
    b[index]=a[index]
   .....:     
In [641]: b
Out[641]: 
array([[array([0, 1]), array([2, 3]), array([4, 5])],
       [array([6, 7]), array([8, 9]), array([10, 11])]], dtype=object)

由于它使用迭代,因此不理想。但我想知道是否有可能以任何其他方式访问b的元素。通过使用dtype=object,您可以打破numpy已知的基本矢量化。 b本质上是一个包含numpy多重阵列形状叠加层的列表。 dtype=object在那些2号阵列周围留下了难以穿透的墙。

例如,a[:,:,0]在(2,3)数组中给出了所有偶数。我只能通过索引从b获取这些数字。我必须使用迭代:

[b[index][0] for index in np.ndindex(b.shape)]
# [0, 2, 4, 6, 8, 10]

考虑到数据的规律性,

np.array尝试制作最高维数组。为了欺骗它制作一个对象数组,我们必须给出一个不规则的列表或对象列表。例如,我们可以:

mylist = list(a.reshape(-1,2)) # list of arrays
mylist.append([]) # make the list irregular
b = np.array(mylist)  # array of objects
b = b[:-1].reshape(2,3)  # cleanup

最后一个解决方案表明我的第一个可以清理一下:

b = np.empty((6,),dtype=object)
b[:] = list(a.reshape(-1,2))
b = b.reshape(2,3)

我怀疑在list()调用下,[x for x in a.reshape(-1,2)] 调用会执行类似

的迭代
ndindex

因此,时间可能与b时间没有多大差别。


我对a没有期待的一件事是,我可以对它进行数学运算,与b-10 b += 10 b *= 2 上的通用性基本相同:

In [785]: b1=np.zeros((2,3),dtype=[('f0',int,(2,))])

In [786]: b1['f0'][:]=a

In [787]: b1
Out[787]: 
array([[([0, 1],), ([2, 3],), ([4, 5],)],
       [([6, 7],), ([8, 9],), ([10, 11],)]], 
      dtype=[('f0', '<i4', (2,))])

In [788]: b1['f0']
Out[788]: 
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11]]])

In [789]: b1[1,1]['f0']
Out[789]: array([8, 9])

对象dtype的替代方案是结构化dtype,例如

b

可以添加b1b+b1object(生成{{1}} dtype)。 Curiouser和curiouser!

答案 1 :(得分:0)

基于hpaulj,我提供了一个更通用的解决方案。 a是维N的数组,它应转换为维N1的数组b,dtype对象保存维数(N-N1)。 在示例中,N等于5,N1等于3.

import numpy as np

N=5
N1=3

#create array a with dimension N
a=np.random.random(np.random.randint(2,20,size=N))

a_shape=a.shape
b_shape=a_shape[:N1] # shape of array b
b_arr_shape=a_shape[N1:] # shape of arrays in b

#Solution 1 with list() method (faster)
b=np.empty(np.prod(b_shape),dtype=object) #init b
b[:]=list(a.reshape((-1,)+b_arr_shape))
b=b.reshape(b_shape)

print "Dimension of b: {}".format(len(b.shape)) # dim of b
print "Dimension of array in b: {}".format(len(b[0,0,0].shape)) # dim of arrays in b

#Solution 2 with ndindex loop (slower)
b=np.empty(b_shape,dtype=object)
for index in np.ndindex(b_shape):
  b[index]=a[index]

print "Dimension of b: {}".format(len(b.shape)) # dim of b
print "Dimension of array in b: {}".format(len(b[0,0,0].shape)) # dim of arrays in b