Python numpy recarray : Can one obtain a view into different fields using pointer arithmetic?

标签 python numpy recarray

我有一个以下形式的 numpy 结构化数组:

x = np.array([(1,2,3)]*2, [('t', np.int16), ('x', np.int8), ('y', np.int8)])

我现在想生成此数组的 View ,将 ''x''y' 组合在一起。通常的语法创建一个副本:

v_copy = x[['t', 'y']]
v_copy
#array([(1, 3), (1, 3)], 
#     dtype=[('t', '<i2'), ('y', '|i1')])

v_copy.base is None
#True

这并不意外,因为选择两个字段是“花哨的索引”,此时 numpy 放弃并制作副本。由于我的实际记录很大,所以我想不惜一切代价避免复制。

在 numpy 的跨步内存模型中无法访问所需的元素根本不是真的。查看内存中的各个字节:

x.view(np.int8)
#array([1, 0, 2, 3, 1, 0, 2, 3], dtype=int8)

可以找出必要的步骤:

v = np.recarray((2,2), [('b', np.int8)], buf=x, strides=(4,3))
v
#rec.array([[(1,), (3,)],
#    [(1,), (3,)]], 
#    dtype=[('b', '|i1')])
v.base is x
#True

显然,v 指向内存中的正确位置,而无需创建副本。不幸的是,numpy 不允许我将这些内存位置重新解释为原始数据类型:

v_view = v.view([('t', np.int16), ('y', np.int8)])
#ValueError: new type not compatible with array.

有没有办法欺骗 numpy 进行这种转换,从而创建一个等同于 v_copy 的数组 v_view,但没有制作副本?也许直接在 v.__array_interface__ 上工作,就像在 np.lib.stride_tricks.as_strided() 中所做的那样?

最佳答案

你可以像这样构造一个合适的数据类型

dt2 = np.dtype(dict(names=('t', 'x'), formats=(np.int16, np.int8), offsets=(0, 2)))

然后做

y = np.recarray(x.shape, buf=x, strides=x.strides, dtype=dt2)

在未来的 Numpy 版本中(> 1.6),你也可以这样做

dt2 = np.dtype(dict(names=('t', 'x'), formats=(np.int16, np.int8), offsets=(0, 2), itemsize=4))
y = x.view(dt2)

关于Python numpy recarray : Can one obtain a view into different fields using pointer arithmetic?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11774168/

相关文章:

python - 从 Numpy Rec 数组中选择行

python - 子类空 numpy recarray 丢失其类型并在 numpy 1.8 中添加属性

Python Numpy recarray 排序双向

python - 在 python 3.3 中安装 suds

python - "Three-bonacchi"序列

python - Selenium 留下正在运行的进程?

python - numpy,取它们交集的数组差

python - 如何仅在使用 Python 找到特定模式后才能读取 csv 文件?

python - 2 个矩阵中行的点积

python - 使用两个隐式循环迭代数组