将 numpy 数组转换为 numpy 数组的数组
Convert a numpy array to an array of numpy arrays
如何以 (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])
首先:
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])
和b
和b1
可以相加:b+b1
(产生一个object
dtype)。越来越好奇!
基于 hpaulj,我提供了一个更通用的解决方案。 a
是一个 N 维数组,应将其转换为一个 b
维 N1 数组,其中 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
如何以 (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])
首先:
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])
和b
和b1
可以相加:b+b1
(产生一个object
dtype)。越来越好奇!
基于 hpaulj,我提供了一个更通用的解决方案。 a
是一个 N 维数组,应将其转换为一个 b
维 N1 数组,其中 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