Arrays 取每个条目的最小值+;-numpy数组中两侧各有10行

Arrays 取每个条目的最小值+;-numpy数组中两侧各有10行,arrays,numpy,scipy,minimum,Arrays,Numpy,Scipy,Minimum,我有一个3d numpy数组,并希望为每个2d数组生成一个二级数组,该数组由每个值的最小值以及正上方10行和正下方10行中的值组成(即每个条目是21个值中的最小值) 我一直在尝试使用'numpy.clip'来处理数组的边缘-在这里,取最小值的值范围应该在数组的顶部/底部的值处减少到10。我想像“scipy.signal.argrelmin”这样的东西似乎就是我想要的 以下是我迄今为止的代码,肯定不是最好的方法: import numpy as np array_3d = np.random.r

我有一个3d numpy数组,并希望为每个2d数组生成一个二级数组,该数组由每个值的最小值以及正上方10行和正下方10行中的值组成(即每个条目是21个值中的最小值)

我一直在尝试使用'numpy.clip'来处理数组的边缘-在这里,取最小值的值范围应该在数组的顶部/底部的值处减少到10。我想像“scipy.signal.argrelmin”这样的东西似乎就是我想要的

以下是我迄今为止的代码,肯定不是最好的方法:

import numpy as np

array_3d = np.random.random_integers(50, 80, (3, 50, 18))
minimums = np.zeros(array_3d.shape)

for array_2d_index in range(len(array_3d)):
    for row_index in range(len(array_3d[array_2d_index])):
        for col_index in range(len(array_3d[array_2d_index][row_index])):
            minimums[array_2d_index][row_index][col_index] = min(array_3d[array_2d_index][np.clip(row_index-10, 0, 49):np.clip(row_index+10, 0, 49)][col_index])
我认为主要的问题是,这是从每个条目任一侧的列中获取最小值,而不是从给出索引错误的行中获取最小值

非常感谢您的建议。

方法#1

这里有一种方法-

样本运行-

1) 输入:

2) 大踏步的观点:

In [180]: strided_3D_axis1(array_3d, L=3)
Out[180]: 
array([[[[73, 65, 51, 76, 59],
         [74, 57, 75, 53, 70],
         [60, 74, 52, 54, 60]],

        [[74, 57, 75, 53, 70],
         [60, 74, 52, 54, 60],
         [54, 52, 62, 75, 50]],

        [[60, 74, 52, 54, 60],
         [54, 52, 62, 75, 50],
         [68, 56, 68, 63, 77]]],


       [[[62, 70, 60, 79, 74],
         [70, 68, 50, 74, 57],
         [63, 57, 69, 65, 54]],

        [[70, 68, 50, 74, 57],
         [63, 57, 69, 65, 54],
         [63, 63, 68, 58, 60]],

        [[63, 57, 69, 65, 54],
         [63, 63, 68, 58, 60],
         [70, 66, 65, 78, 78]]]])
3) 基于跨步视图的
min

In [181]: strided_3D_axis1(array_3d, L=3).min(axis=-2)
Out[181]: 
array([[[60, 57, 51, 53, 59],
        [54, 52, 52, 53, 50],
        [54, 52, 52, 54, 50]],

       [[62, 57, 50, 65, 54],
        [63, 57, 50, 58, 54],
        [63, 57, 65, 58, 54]]])
方法#2

下面是创建沿第二轴的所有滑动索引时的另一个示例-

array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
方法#3

这是另一个例子-


运行时测试-

In [231]: array_3d = np.random.randint(50, 80, (3, 50, 18))

In [232]: %timeit strided_3D_axis1(array_3d, L=21).min(axis=-2)
10000 loops, best of 3: 54.2 µs per loop

In [233]: %timeit array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
10000 loops, best of 3: 81.3 µs per loop

In [234]: L = 21
     ...: hL = (L-1)//2
     ...: 

In [235]: %timeit minf(array_3d,L,axis=1)[:,hL:-hL]
10000 loops, best of 3: 32 µs per loop

谢谢我已经测试了这些,发现如果最小值(例如randint中的50)在数组的边缘(例如在最下面一行),那么直接上面的10个值不等于50,而是更高。@JGraham353使用所有三种方法?还有,“L”应该被设置为11,只允许值的范围是直接在上面的10行和直接给定值以下的10行?@ JGRAHAM353,所以对于边缘元素,我们将没有10行和下面的窗口,你想考虑有多少可用,对吗?例如,对于最后一行,我们只会有该行本身和它上面的10行,也就是说,它只会尝试在11行中找到可用的最小值。这是一个正确的假设吗?@JGraham353那么,只需使用最后一种方法而不进行切片:
minf(array_3d,21,axis=1)
array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
from scipy.ndimage.filters import minimum_filter1d as minf

L = 21
hL = (L-1)//2
out = minf(array_3d,L,axis=1)[:,hL:-hL]
In [231]: array_3d = np.random.randint(50, 80, (3, 50, 18))

In [232]: %timeit strided_3D_axis1(array_3d, L=21).min(axis=-2)
10000 loops, best of 3: 54.2 µs per loop

In [233]: %timeit array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
10000 loops, best of 3: 81.3 µs per loop

In [234]: L = 21
     ...: hL = (L-1)//2
     ...: 

In [235]: %timeit minf(array_3d,L,axis=1)[:,hL:-hL]
10000 loops, best of 3: 32 µs per loop