numpy数组中的元素排列


import numpy as np
data = np.array([[0, 0, 1, 1, 2, 2],
                 [1, 0, 0, 1, 2, 2],
                 [1, 0, 1, 0, 0, 0],
                 [1, 1, 0, 0, 2, 0]])

我如何做以下事情?

在2 × 2补丁内:

if any element is 2: put 2
if any element is 1: put 1
if all elements are 0: put 0

预期结果是:

np.array([[1, 1, 2],
          [1, 1, 2]])

使用scikit-learn中的extract_patches,你可以这样写(复制和粘贴代码):

import numpy as np
from sklearn.feature_extraction.image import extract_patches
data = np.array([[0, 0, 1, 1, 2, 2],
                 [1, 0, 0, 1, 2, 2],
                 [1, 0, 1, 0, 0, 0],
                 [1, 1, 0, 0, 2, 0]])
patches = extract_patches(data, patch_shape=(2, 2), extraction_step=(2, 2))
output = patches.max(axis=-1).max(axis=-1)

解释: extract_patches给你一个关于你的数组补丁的视图,大小为patch_shape,躺在extraction_step的网格上。结果是一个四维数组,其中前两个轴索引补丁,最后两个轴索引补丁内的像素。然后,我们评估最后两个轴的最大值,以获得每个补丁的最大值。

EDIT这实际上与这个问题非常相关

我不知道你从哪里得到你的输入,或者你应该离开输出,但你可以适应这一点。

import numpy as np
data = np.array([[0, 0, 1, 1, 2, 2],
                 [1, 0, 0, 1, 2, 2],
                 [1, 0, 1, 0, 0, 0],
                 [1, 1, 0, 0, 2, 0]])
def patchValue(i,j):
    return max([data[i][j],
                data[i][j+1],
                data[i+1][j],
                data[i+1][j+1]])
result = np.array([[0, 0, 0],
                   [0, 0, 0]])
for (v,i) in enumerate(range(0,4,2)):
    for (w,j) in enumerate(range(0,6,2)):
        result[v][w] = patchValue(i,j)
print(result)

这是一个相当长的一行代码,它完全依赖于重塑、转置和沿不同轴取最大值。它也相当快。

data.reshape((-1,2)).max(axis=1).reshape((data.shape[0],-1)).T.reshape((-1,2)).max(axis=1).reshape((data.shape[1]/2,data.shape[0]/2)).T

本质上,它所做的是重塑,以两个成对的水平取最大值,然后再次洗牌,并以两个成对的垂直取最大值,最终给出每个块4的最大值,匹配您想要的输出。

如果原始数组很大,并且性能是一个问题,可以通过操纵原始数组的形状和步长来创建您正在操作的窗口,从而将循环下推到numpy C代码中:

import numpy as np
from numpy.lib.stride_tricks import as_strided
data = np.array([[0, 0, 1, 1, 2, 2],
                 [1, 0, 0, 1, 2, 2],
                 [1, 0, 1, 0, 0, 0],
                 [1, 1, 0, 0, 2, 0]])
patch_shape = (2,2)
data_shape = np.array(data.shape)
# transform data to a 2x3 array of 2x2 patches/windows
# final shape of the computation on the windows can be calculated with:
# tuple(((data_shape-patch_shape) // patch_shape) + 1)
final_shape = (2,3)
# the shape of the windowed array can be calculated with:
# final_shape + patch_shape
newshape = (2, 3, 2, 2)
# the strides of the windowed array can be calculated with:
# tuple(np.array(data.strides) * patch_shape) + data.strides
newstrides = (48, 8, 24, 4)
# use as_strided to 'transform' the array
patch_array = as_strided(data, shape = newshape, strides = newstrides)
# flatten the windowed array for iteration - dim of 6x2x2
# the number of windows is the product of the 'first' dimensions of the array
# which can be calculated with:
# (np.product(newshape[:-len(patch_shape)])) + (newshape[-len(patch_array):])
dim = (6,2,2)
patch_array = patch_array.reshape(dim)
# perfom computations on the windows and reshape to final dimensions
result = [2 if np.any(patch == 2) else
          1 if np.any(patch == 1) else
          0 for patch in patch_array]
result = np.array(result).reshape(final_shape)

用于创建窗口数组的广义1-d函数可以在Efficient rolling statistics with NumPy中找到

一个广义的多维函数和一个很好的解释可以在Numpy高效重叠窗口中找到

相关内容

  • 没有找到相关文章

最新更新