如何将数组转换为结构化数组的特殊项目并将其还原?

问题描述

我想对结构化数组的项目而不是数字执行一些numpy方法。因此,例如,在处理形状为(4,3)的整数数组时,我需要将其转换为长度为3的项数组,并执行某些操作,因为它是形状(4,)的单个一维数组。不幸的是,这些转换本身对我来说看起来真的很复杂。让我们再举一个例子:

n,m,r = 2,3,4
array = np.arange(n*m).reshape((n,m))
dt = np.dtype(','.join('i'*m))
arr1 = np.array([tuple(x) for x in array],dtype=dt)
>>> arr1
array([(0,1,2),(3,4,5)],dtype=[('f0','<i4'),('f1',('f2','<i4')])

然后我在其上调用一些方法,为简单起见,将其设为np.tile(但它们可能完全不同):

arr2 = np.tile(arr1[:,None],r)
>>> arr2
array([[(0,(0,2)],[(3,5),5)]],'<i4')])

我想将其转换为该数组:

array([[[0,2],[0,2]],[[3,5],[3,5]]]

我有两个问题:

  1. 如何将array转换为arr1(一堆特殊项目)而无需迭代?
  2. 如何将arr2(一堆特殊项目)转换回我想要的单个项目数组?

解决方法

numpy提供了用于执行此操作的辅助功能:

>>> n,m,r = 2,3,4
>>> array = np.arange(n*m).reshape((n,m))
>>> import numpy.lib.recfunctions as recfunctions
>>> recfunctions.unstructured_to_structured(array,dtype=np.dtype(','.join('i'*m)))
array([(0,1,2),(3,4,5)],dtype=[('f0','<i4'),('f1',('f2','<i4')])

另一个方向:

>>> import numpy.lib.recfunctions as recfunctions
>>> recfunctions.structured_to_unstructured(arr2)
array([[[0,2],[0,2]],[[3,5],[3,5]]],dtype=int32)

在这种特殊情况下,如果原始数组为dtype=np.int32,则可以使用视图:

>>> array = np.arange(n*m,dtype=np.int32).reshape((n,m))
>>> structured_view = array.view(dtype=np.dtype(','.join('i'*m)))
>>> structured_view
array([[(0,2)],[(3,5)]],'<i4')])

视图的优点是它创建了一个新的数组。当然,如果您更改视图并且不希望原始数组也发生变化,这可能是缺点

相反,它无法处理您想要的形状,但您始终可以重新塑形:

>>> arr2.view(dtype=np.int32)
array([[0,2,5,5]],dtype=int32)

使用视图可能会变得棘手,快速。