我有以下形式的 numpy 结构化数组:
x = np.array([(1,2,3)]*2, [('t', np.int16), ('x', np.int8), ('y', np.int8)])
我现在想在这个数组中生成't'
与'x'
or 或'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_view
等效于的数组v_copy
,但没有制作副本?也许直接工作v.__array_interface__
,就像在做的那样np.lib.stride_tricks.as_strided()
?