2012-10-14 34 views
4

我有一个2维阵列,其中我需要提取切片(切片)到一个新的数组:numpy的:组装多个切片成新的数组

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循环)?

---- ---- EDIT

为了澄清,我要求如何复制任意(但是类似)状从2D阵列到另一个的任意二维索引的二维切片,垂直堆叠 - 不是特别沿着对角线或2x2大小。

+0

切片是否必须是方形的? – Bitwise

+0

@Bitwise“任意(但类似)成型2D切片”,所以,不一定是正方形 – goncalopp

回答

1

这里是您的解决方案:

v = np.arange(0,original.shape[0],0.5).astype(int) 
result = np.c_[ original[v[1:-1],v[:-2]] , original[v[1:-1],v[2:]] ] 

作品方形输入矩阵(“原始”你叫吧)中的任何尺寸。

这个想法是创建一个“辅助数组”v,它简单地[0,0,1,1,2,2,3,3,...],然后使用观察你的指数需要总是简单的切片v。

享受!

+0

我仍然试图理解,在第二行锯齿...有没有办法在任意切片尺寸上做到这一点(不一定2×2)?并且对于任意切片位置,不一定沿着对角线。 – goncalopp

+0

@goncalopp任意方形切片大小应该是一个简单的扩展。任意位置可能会更棘手 - 底线是您可以使用索引获取切片,您只需列出正确的顺序即可。无论如何,你的问题是非常具体的,并且不清楚你想概括哪些变量,所以如果你想要某些特定的东西,请把它放在问题中。 – Bitwise

+0

如果我正确理解你的方法,提取n * n个大小的片将需要n个参数np.c_?我编辑了这个问题的澄清 – goncalopp

3

有一个漂亮的把戏与stride_tricks,你可以找到在滚动不同一般性窗口功能,以便和其他(当前有没有在numpy的本身),这里是适合你得到了什么版本:

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的视图,旧的视图总是副本):

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())。

编辑:既然slices阵列是2D的,而不是3D的,因为你追加,一个重塑缺少这里:

slices = diagonal.reshape(-1,2) 

,如果你有这样的小数组这可能不是快,但它的常数(期待数据复制diagonal调用)与数组大小。

+0

这简化了索引,但是如何在不使用numpy.append的情况下使用它来实现最终数组(问题中的“切片”)呢? – goncalopp

+0

@goncalopp对不起,我错过了,而追加你删除一个维度。这只是一个重塑而已。添加它,虽然它可能有点烦人。我不确定你到底想要什么,但视图可以帮助你去切片,从那里取决于我猜... – seberg

+0

不错!有没有办法将其推广到任意索引(不一定在对角线上)? (查看问题编辑) – goncalopp