numpy数组中的元素排列

时间:2021-12-14 01:42:53
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]])

How can I do the followings?

我怎样才能做到以下几点?

Within 2 by 2 patch:

在2乘2补丁:

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

The expected result is:

预期的结果是:

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

4 个解决方案

#1


4  

Using extract_patches from scikit-learn you can write this as follows (copy and paste-able code):

使用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)

Explanation: extract_patches gives you a view on patches of your array, of size patch_shape and lying on a grid of extraction_step. The result is a 4D array where the first two axes index the patch and the last two axes index the pixels within the patch. We then evaluate the maximum over the last two axes to obtain the maximum per patch.

说明:extract_patches为您提供了数组补丁的视图,补丁大小为patch_shape,位于extract_step的网格上。结果是一个4D阵列,其中前两个轴索引补丁,最后两个轴索引补丁内的像素。然后,我们评估最后两个轴的最大值,以获得每个补丁的最大值。

EDIT This is actually very much related to this question

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

#2


2  

I'm not sure where you get your input from or where you are supposed to leave the output, but you can adapt this.

我不确定你从哪里得到你的输入或你应该离开输出的地方,但你可以调整它。

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)

#3


1  

Here's a rather lengthy one-liner that relies solely on reshaping, transposes, and taking maximums along different axes. It is fairly fast too.

这是一个相当冗长的单线程,完全依赖于重塑,转置和沿不同轴的最大值。它也相当快。

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

Essentially what this does is reshape to take the maximum in pairs of two horizontally, then shuffle things around again and take the maximum in pairs of two vertically, ultimately giving the maximum of each block of 4, matching your desired output.

基本上它的作用是重新塑造成两个水平对的最大值,然后再次移动物体并垂直取两个最大值,最终给出每个块的最大值4,与您想要的输出相匹配。

#4


0  

If the original array is large, and performance is an issue, the loops can be pushed down to numpy C code by manipulating the shape and strides of the original array to create the windows that you are acting on:

如果原始数组很大,并且性能是个问题,那么可以通过操纵原始数组的形状和步幅来创建您正在操作的窗口,从而将循环推送到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)

A generalized 1-d function for creating the windowed array can be found at Efficient rolling statistics with NumPy

可以在使用NumPy的高效滚动统计中找到用于创建窗口数组的通用1-d函数

A generalised multi-dimension function and a nice explanation can be found at Efficient Overlapping Windows with Numpy

可以在Efficient Overlapping Windows with Numpy中找到一个通用的多维函数和一个很好的解释

#1


4  

Using extract_patches from scikit-learn you can write this as follows (copy and paste-able code):

使用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)

Explanation: extract_patches gives you a view on patches of your array, of size patch_shape and lying on a grid of extraction_step. The result is a 4D array where the first two axes index the patch and the last two axes index the pixels within the patch. We then evaluate the maximum over the last two axes to obtain the maximum per patch.

说明:extract_patches为您提供了数组补丁的视图,补丁大小为patch_shape,位于extract_step的网格上。结果是一个4D阵列,其中前两个轴索引补丁,最后两个轴索引补丁内的像素。然后,我们评估最后两个轴的最大值,以获得每个补丁的最大值。

EDIT This is actually very much related to this question

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

#2


2  

I'm not sure where you get your input from or where you are supposed to leave the output, but you can adapt this.

我不确定你从哪里得到你的输入或你应该离开输出的地方,但你可以调整它。

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)

#3


1  

Here's a rather lengthy one-liner that relies solely on reshaping, transposes, and taking maximums along different axes. It is fairly fast too.

这是一个相当冗长的单线程,完全依赖于重塑,转置和沿不同轴的最大值。它也相当快。

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

Essentially what this does is reshape to take the maximum in pairs of two horizontally, then shuffle things around again and take the maximum in pairs of two vertically, ultimately giving the maximum of each block of 4, matching your desired output.

基本上它的作用是重新塑造成两个水平对的最大值,然后再次移动物体并垂直取两个最大值,最终给出每个块的最大值4,与您想要的输出相匹配。

#4


0  

If the original array is large, and performance is an issue, the loops can be pushed down to numpy C code by manipulating the shape and strides of the original array to create the windows that you are acting on:

如果原始数组很大,并且性能是个问题,那么可以通过操纵原始数组的形状和步幅来创建您正在操作的窗口,从而将循环推送到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)

A generalized 1-d function for creating the windowed array can be found at Efficient rolling statistics with NumPy

可以在使用NumPy的高效滚动统计中找到用于创建窗口数组的通用1-d函数

A generalised multi-dimension function and a nice explanation can be found at Efficient Overlapping Windows with Numpy

可以在Efficient Overlapping Windows with Numpy中找到一个通用的多维函数和一个很好的解释