如何将数组转换为结构化数组的特殊项并将其还原?
How to convert array into special items of structured array and revert it back?
我想对结构化数组的项目而不是数字执行一些 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', '<i4'), ('f2', '<i4')])
然后我在上面调用一些方法,为了简单起见,让它成为np.tile
(但它们可能完全不同):
arr2 = np.tile(arr1[:,None], r)
>>> arr2
array([[(0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2)],
[(3, 4, 5), (3, 4, 5), (3, 4, 5), (3, 4, 5)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
我想将它转换成这个数组:
array([[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
[[3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5]]]
我有两个问题:
- 如何在不迭代的情况下将
array
转换为arr1
(一堆特殊物品)?
- 如何将
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', '<i4'), ('f2', '<i4')])
而在另一个方向:
>>> import numpy.lib.recfunctions as recfunctions
>>> recfunctions.structured_to_unstructured(arr2)
array([[[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]],
[[3, 4, 5],
[3, 4, 5],
[3, 4, 5],
[3, 4, 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, 1, 2)],
[(3, 4, 5)]], dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
视图的优点是它创建了一个新数组。当然,如果您改变视图并且不希望原始数组也发生变化,这可能是一个缺点。
相反,它无法处理您想要的形状,但您可以随时重塑:
>>> arr2.view(dtype=np.int32)
array([[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]], dtype=int32)
使用视图可能会很棘手,但速度很快。
我想对结构化数组的项目而不是数字执行一些 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', '<i4'), ('f2', '<i4')])
然后我在上面调用一些方法,为了简单起见,让它成为np.tile
(但它们可能完全不同):
arr2 = np.tile(arr1[:,None], r)
>>> arr2
array([[(0, 1, 2), (0, 1, 2), (0, 1, 2), (0, 1, 2)],
[(3, 4, 5), (3, 4, 5), (3, 4, 5), (3, 4, 5)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
我想将它转换成这个数组:
array([[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],
[[3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5]]]
我有两个问题:
- 如何在不迭代的情况下将
array
转换为arr1
(一堆特殊物品)? - 如何将
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', '<i4'), ('f2', '<i4')])
而在另一个方向:
>>> import numpy.lib.recfunctions as recfunctions
>>> recfunctions.structured_to_unstructured(arr2)
array([[[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]],
[[3, 4, 5],
[3, 4, 5],
[3, 4, 5],
[3, 4, 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, 1, 2)],
[(3, 4, 5)]], dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
视图的优点是它创建了一个新数组。当然,如果您改变视图并且不希望原始数组也发生变化,这可能是一个缺点。
相反,它无法处理您想要的形状,但您可以随时重塑:
>>> arr2.view(dtype=np.int32)
array([[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]], dtype=int32)
使用视图可能会很棘手,但速度很快。