如何获取结构化数组选择的副本
How to get copy of structured array selection
我有一个混合类型的结构化数组:
dt = np.dtype([('x', np.float64), ('y', np.float64), ('n', np.uint32)])
arr = np.empty(10, dtype=dt)
从 numpy 1.16 左右开始,如果我查看 x
和 y
,我会得到一个视图:
>>> sub = arr[['x', 'y']]
>>> sub
array([(6.23042070e-307, 4.67296746e-307),
(1.15710088e-306, 1.60221615e-306),
(1.95821574e-306, 6.23062102e-307),
(1.78019082e-306, 1.37959740e-306),
(1.37959129e-306, 1.33511562e-306),
(1.33511018e-306, 1.33511969e-306),
(1.11261027e-306, 1.11261502e-306),
(8.45593934e-307, 9.34600963e-307),
(6.23038336e-307, 1.29061142e-306),
(2.22522596e-306, 2.22522596e-306)],
dtype={'names':['x','y'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':20})
这是一个问题,因为我希望能够将子集 sub
转换为 x
和 y
字段的 (10, 2)
视图。
我不能只使用 sub.view(dtype=np.float64)
。这引发了错误
ValueError: When changing to a smaller dtype, its size must be a divisor of the size of original dtype
我可以使用 np.lib.stride_tricks.as_strided
,但这很麻烦而且有问题,因为它只在我需要两个字段(或者任意数量的均匀间隔的字段)时有效:
>>> shape = sub.shape + (2,)
>>> strides = (sub.dtype.itemsize,
np.diff([x[1] for x in sub.dtype.fields.values()]).item())
>>> np.lib.stride_tricks.as_strided(sub, shape=shape, strides=strides)['x']
array([[6.23042070e-307, 4.67296746e-307],
[1.15710088e-306, 1.60221615e-306],
[1.95821574e-306, 6.23062102e-307],
[1.78019082e-306, 1.37959740e-306],
[1.37959129e-306, 1.33511562e-306],
[1.33511018e-306, 1.33511969e-306],
[1.11261027e-306, 1.11261502e-306],
[8.45593934e-307, 9.34600963e-307],
[6.23038336e-307, 1.29061142e-306],
[2.22522596e-306, 2.22522596e-306]])
如果 sub
是一个副本,那么我可以简单地将其视为一个 (10, 2)
浮点数组。如何通过复制选择或任何其他方式将所选字段视为此类数组?
repack_fields
随着多视场视图的变化而变化:
In [135]: dt = np.dtype([('x', np.float64), ('y', np.float64), ('n', np.uint32)])
...: arr = np.empty(3, dtype=dt)
In [136]: sub = arr[['x','y']]
In [137]: import numpy.lib.recfunctions as rf
In [138]: rf.repack_fields(sub)
Out[138]:
array([(4.04359530e-316, 4.04349886e-316),
(0.00000000e+000, 0.00000000e+000),
(4.04355735e-316, 0.00000000e+000)],
dtype=[('x', '<f8'), ('y', '<f8')])
In [139]: sub
Out[139]:
array([(4.04359530e-316, 4.04349886e-316),
(0.00000000e+000, 0.00000000e+000),
(4.04355735e-316, 0.00000000e+000)],
dtype={'names':['x','y'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':20})
这是副本,不是视图。
对于 (n,2) 个副本:
In [140]: rf.structured_to_unstructured(sub)
Out[140]:
array([[4.04359530e-316, 4.04349886e-316],
[0.00000000e+000, 0.00000000e+000],
[4.04355735e-316, 0.00000000e+000]])
In [141]: rf.structured_to_unstructured(rf.repack_fields(sub))
Out[141]:
array([[4.04359530e-316, 4.04349886e-316],
[0.00000000e+000, 0.00000000e+000],
[4.04355735e-316, 0.00000000e+000]])
我有一个混合类型的结构化数组:
dt = np.dtype([('x', np.float64), ('y', np.float64), ('n', np.uint32)])
arr = np.empty(10, dtype=dt)
从 numpy 1.16 左右开始,如果我查看 x
和 y
,我会得到一个视图:
>>> sub = arr[['x', 'y']]
>>> sub
array([(6.23042070e-307, 4.67296746e-307),
(1.15710088e-306, 1.60221615e-306),
(1.95821574e-306, 6.23062102e-307),
(1.78019082e-306, 1.37959740e-306),
(1.37959129e-306, 1.33511562e-306),
(1.33511018e-306, 1.33511969e-306),
(1.11261027e-306, 1.11261502e-306),
(8.45593934e-307, 9.34600963e-307),
(6.23038336e-307, 1.29061142e-306),
(2.22522596e-306, 2.22522596e-306)],
dtype={'names':['x','y'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':20})
这是一个问题,因为我希望能够将子集 sub
转换为 x
和 y
字段的 (10, 2)
视图。
我不能只使用 sub.view(dtype=np.float64)
。这引发了错误
ValueError: When changing to a smaller dtype, its size must be a divisor of the size of original dtype
我可以使用 np.lib.stride_tricks.as_strided
,但这很麻烦而且有问题,因为它只在我需要两个字段(或者任意数量的均匀间隔的字段)时有效:
>>> shape = sub.shape + (2,)
>>> strides = (sub.dtype.itemsize,
np.diff([x[1] for x in sub.dtype.fields.values()]).item())
>>> np.lib.stride_tricks.as_strided(sub, shape=shape, strides=strides)['x']
array([[6.23042070e-307, 4.67296746e-307],
[1.15710088e-306, 1.60221615e-306],
[1.95821574e-306, 6.23062102e-307],
[1.78019082e-306, 1.37959740e-306],
[1.37959129e-306, 1.33511562e-306],
[1.33511018e-306, 1.33511969e-306],
[1.11261027e-306, 1.11261502e-306],
[8.45593934e-307, 9.34600963e-307],
[6.23038336e-307, 1.29061142e-306],
[2.22522596e-306, 2.22522596e-306]])
如果 sub
是一个副本,那么我可以简单地将其视为一个 (10, 2)
浮点数组。如何通过复制选择或任何其他方式将所选字段视为此类数组?
repack_fields
随着多视场视图的变化而变化:
In [135]: dt = np.dtype([('x', np.float64), ('y', np.float64), ('n', np.uint32)])
...: arr = np.empty(3, dtype=dt)
In [136]: sub = arr[['x','y']]
In [137]: import numpy.lib.recfunctions as rf
In [138]: rf.repack_fields(sub)
Out[138]:
array([(4.04359530e-316, 4.04349886e-316),
(0.00000000e+000, 0.00000000e+000),
(4.04355735e-316, 0.00000000e+000)],
dtype=[('x', '<f8'), ('y', '<f8')])
In [139]: sub
Out[139]:
array([(4.04359530e-316, 4.04349886e-316),
(0.00000000e+000, 0.00000000e+000),
(4.04355735e-316, 0.00000000e+000)],
dtype={'names':['x','y'], 'formats':['<f8','<f8'], 'offsets':[0,8], 'itemsize':20})
这是副本,不是视图。
对于 (n,2) 个副本:
In [140]: rf.structured_to_unstructured(sub)
Out[140]:
array([[4.04359530e-316, 4.04349886e-316],
[0.00000000e+000, 0.00000000e+000],
[4.04355735e-316, 0.00000000e+000]])
In [141]: rf.structured_to_unstructured(rf.repack_fields(sub))
Out[141]:
array([[4.04359530e-316, 4.04349886e-316],
[0.00000000e+000, 0.00000000e+000],
[4.04355735e-316, 0.00000000e+000]])