numpy:将多个切片组装到新数组中 [英] numpy : assembling multiple slices into new array

查看:181
本文介绍了numpy:将多个切片组装到新数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个二维数组,我需要将其切片(切片)提取到新数组中:

I have a 2-dimentional array, of which I need to extract sections (slices) into a new array:

original= numpy.ndarray( shape=(4,4) )
slices= numpy.ndarray( shape=(0,2) )
for x in range(3):
    slice= original[x:x+2,x:x+2] 
    slices=numpy.append(slices, slice,axis=0)

是否有一种更有效的方法(摆脱python的循环)?

Is there a more efficient way to do this (getting rid of the python for cycle)?

----编辑----

为澄清起见,我想问的是如何将2D数组的任意2D索引中任意(但类似)成形的2D切片复制到另一个垂直堆叠的对象中-特别不是沿对角线或2x2大小.

To clarify, I'm asking how to copy arbitrarily (but similarly) shaped 2D slices from arbitrary 2D indexes of an 2D array into another, vertically stacked - not particularly along the diagonal, or 2x2 sized.

推荐答案

stride_tricks有一个妙招,您可以在SO和其他代码上找到具有不同通用性的滚动窗口函数(目前numpy本身还没有这种函数),这是一个针对您所得到的版本:

There is a nifty trick with stride_tricks, you can find rolling window functions with different generality on SO and other (there currently is none in numpy itself), here is a version tailored to what you got:

def rolling_window(arr, window):
    """Very basic multi dimensional rolling window. window should be the shape of
    of the desired subarrays. Window is either a scalar or a tuple of same size
    as `arr.shape`.
    """
    shape = np.array(arr.shape*2)
    strides = np.array(arr.strides*2)
    window = np.asarray(window)
    shape[arr.ndim:] = window # new dimensions size
    shape[:arr.ndim] -= window - 1
    if np.any(shape < 1):
        raise ValueError('window size is too large')
    return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

# Now:
view = rolling_window(arr, 2)
view[0,0] # first slice in your loop

请注意,view与原始数组保存的数据相同!这可能会导致意外的结果.但是您似乎只想要对角线,也可以使用跨步技巧来做到这一点,以确保不要复制数据(下一个版本将创建带有diagonal的视图,旧版本将始终创建副本):

Note that view holds the same data as the original array! Which can result in unexpected results. But you seem to want only the diagonal, you could do that with stride tricks as well to make sure you do not copy data if you want (next versions will create a view with diagonal, old ones always a copy):

diagonal = np.diagonal(view, axis1=0, axis2=1)
# unfortunatly now the first slice is diagonal[...,0], so just roll it to the start:
diagonal = np.rollaxis(diagonal, -1)

现在,diagonal是您在for循环中创建的数组(在较新的版本上,如果您不想要视图,请添加.copy()).

Now diagonal is the array you created in your for loop (on newer versions add a .copy() if you do not want a view).

由于slices数组是2D而不是3D数组(因为您追加了),因此此处缺少整形:

Since the slices array is 2D and not 3D because you append, a reshape was missing here:

slices = diagonal.reshape(-1,2)

如果您有这么小的数组,这可能不会更快,但是它的常数(期望在diagonal调用中复制数据)与数组大小有关.

This might not be faster if you have such small arrays, but its constant (expect for the copying of the data in diagonal call) with the array size.

这篇关于numpy:将多个切片组装到新数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆