gpt4 book ai didi

python - 使用 numpy >= 1.13 将特定字段查看为 ndarray

转载 作者:太空宇宙 更新时间:2023-11-04 02:37:27 24 4
gpt4 key购买 nike

数据在结构化数组中:

import numpy as np
dtype = [(field, float) for field in ['x', 'y', 'z', 'prop1', 'prop2']]
data = np.array([(1,2,3,4,5), (6,7,8,9,10), (11,12,13,14,15)], dtype=dtype)

对于某些操作,位置作为单个 nx3 数组访问,例如:

positions = data[['x', 'y', 'z']].view(dtype=float).reshape(-1, 3)
ranges = np.sqrt(np.sum(positions**2, 1))

从 numpy 1.12 开始,会发出以下警告:

FutureWarning: Numpy has detected that you may be viewing or writing to an array returned by selecting multiple fields in a structured array.

This code may break in numpy 1.13 because this will return a view instead of a copy -- see release notes for details.

Here是发行说明中的​​相应条目:

Indexing a structured array with multiple fields (eg, arr[['f1', 'f3']]) will return a view into the original array in 1.13, instead of a copy. Note the returned view will have extra padding bytes corresponding to intervening fields in the original array, unlike the copy in 1.12, which will affect code such as arr[['f1', 'f3']].view(newdtype).

如何将此代码移植到 numpy >=1.13?

最佳答案

检查 numpy 1.13,宣布的更改似乎尚未发生。因此,让我们模拟 future :

future 的行为可能不是复制数据,而是创建一个只有你想要的字段的数据类型,但 itemsize 是原始数据类型的。所以每个元素都会有间隙,没有使用的内存部分。

xyz_tp = xyz_tp = np.dtype({'names': list('xyz'),
'formats': tuple(data.dtype.fields[f][0] for f in 'xyz'),
'offsets': tuple(data.dtype.fields[f][1] for f in 'xyz'),
'itemsize': data.dtype.itemsize})

xyz = data.view(xyz_tp)
xyz
# array([( 1., 2., 3.), ( 6., 7., 8.), ( 11., 12., 13.)],
# dtype={'names':['x','y','z'], 'formats':['<f8','<f8','<f8'], 'offsets':[0,8,16], 'itemsize':40})

未使用的内存位置及其内容将被忽略但仍然存在,因此如果您使用内置 dtype 查看它们将重新出现。

xyz.view(float)
# array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,
# 12., 13., 14., 15.])
# Ouch!

一般的解决方法是转换为具有相同字段的连续(无间隙)dtype。这将强制复制

xyz_cont_tp = np.dtype({'names': list('xyz'), 'formats': 3*('<f8',)})
xyz.astype(xyz_cont_tp).view(float).reshape(-1, 3)
# array([[ 1., 2., 3.],
# [ 6., 7., 8.],
# [ 11., 12., 13.]])

在您选择的字段连续且类型相同的特殊情况下,您还可以:

np.lib.stride_tricks.as_strided(data.view(float), shape=(3,3), strides=data.strides + (8,))
# array([[ 1., 2., 3.],
# [ 6., 7., 8.],
# [ 11., 12., 13.]])

此方法不复制数据,而是创建一个真实的 View 。

关于python - 使用 numpy >= 1.13 将特定字段查看为 ndarray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47550615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com