NumPy数组对非连续项的视图
我有一个一维的numpy数组,里面存的是复数(比如说numpy.complex64)。我想在这个数组上创建视图,但我不知道怎么根据一个索引列表或范围来创建视图。
>>> myArray = np.ndarray(shape=(1000,), dtype=np.complex64)
我知道怎么创建连续元素的视图,比如说前100个元素:
>>> myView = myArray[:100]
我试过,发现不能只对单个元素创建视图,比如myArray[2],因为如果我修改了这个值,底层的数组不会改变。这没问题,但我希望能有办法从多个任意的索引创建视图,这样的话,像这样的函数就太好了:
>>> myView = createView(myArray, indices=(0, 1, 6, 7, 13))
这个函数可以返回一个视图,指向列表中给出的那些索引,如果我改变myView,它也能像应该的那样改变myArray。
这可能吗?或者有没有什么合理的解决办法呢?谢谢。
补充说明:
我需要这样做的原因是:我想把数组复制到OpenCL设备内存(然后再复制回来)。我需要在设备上元素的顺序和原始数组不同,这些较短的数组会被当作向量处理,而矩阵乘法将在OpenCL内核中进行。如果元素没有按照要求的顺序复制到设备内存,就无法实现内存合并,这样会导致性能显著下降,更不用说在OpenCL那边还需要额外的逻辑。
在我的情况下,可以通过均匀间隔的视图来做到这一点,但我想知道是否有更通用的方法。如果能实现更通用的功能,稍微牺牲一点CPU端的性能也是可以接受的。
3 个回答
据我所知,ndarray的视图是这样生成的:myArray.view(dtype)。这里有相关的文档链接:http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.view.html
这并没有解决你提到的非连续项的问题,但我觉得这是一个不错的起点。
我认为你应该用你的索引创建另一个过滤后的数组。因为视图其实和过滤没有太大关系,更多的是同一数据的不同表现方式。
下面展示了提问者的请求:
>>> a = numpy.array(xrange(103,114))
>>> a
array([103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113])
>>> view = numpy.array([2,6,7,9])
>>> a[view]
array([105, 109, 110, 112])
>>> a[view] += 9999
>>> a
array([ 103, 104, 10104, 106, 107, 108, 10108, 10109, 111,
10111, 113])
据我所知,你不能在任意的索引上创建视图;只能在连续的索引或者规则间隔的索引上创建视图。这是因为视图所依赖的内存中的元素必须相隔固定的字节数,否则快速的NumPy操作就无法正常工作。