Python 拆分三维numpy数组,以获得具有满足条件的连续值的所有序列

Python 拆分三维numpy数组,以获得具有满足条件的连续值的所有序列,python,arrays,python-3.x,numpy,vectorization,Python,Arrays,Python 3.x,Numpy,Vectorization,我想得到一个三维数组中沿轴0满足条件的所有数字序列。如果可能的话,我正在尝试将所有内容矢量化,以避免效率极低的循环 下面的代码可以工作,它使用定义的数组,例如形状(6,2,3)。它在其上应用由数组b(相同维度)定义的掩码 然后,我沿着轴0切片我的3D数组,这样我有2*3个1D切片,从而得到6个1D数组的形状(6,)。为了做到这一点,我使用了一个循环,这对于较大的阵列来说显然是一个效率问题 然后,我根据获得的掩码分割数组,并选择(现在只需简单打印)至少有3个连续值满足b数组给定条件的序列 impo

我想得到一个三维数组中沿轴0满足条件的所有数字序列。如果可能的话,我正在尝试将所有内容矢量化,以避免效率极低的循环

下面的代码可以工作,它使用定义的数组,例如形状(6,2,3)。它在其上应用由数组b(相同维度)定义的掩码

然后,我沿着轴0切片我的3D数组,这样我有2*3个1D切片,从而得到6个1D数组的形状(6,)。为了做到这一点,我使用了一个循环,这对于较大的阵列来说显然是一个效率问题

然后,我根据获得的掩码分割数组,并选择(现在只需简单打印)至少有3个连续值满足b数组给定条件的序列

import numpy as np

a = np.array([[[0.57337127, 0.7626088, 0.26965987],
               [0.66987041, 0.2914202, 0.62678441]],
              [[0.97442524, 0.61656519, 0.10544983],
               [0.05780219, 0.00381356, 0.57118615]],
              [[0.47069657, 0.36802822, 0.67483419],
               [0.32773146, 0.99773064, 0.56042508]],
              [[0.70984651, 0.25093198, 0.71911127],
               [0.05182876, 0.9463291, 0.7222756]],
              [[0.56736192, 0.62692889, 0.33814278],
               [0.72362855, 0.12885637, 0.44096788]],
              [[0.12706838, 0.90640269, 0.5126569],
               [0.62920448, 0.24502599, 0.26754067]]])

b = np.array([[[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]],
              [[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]],
              [[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]],
              [[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]],
              [[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]],
              [[0.4, 0.4, 0.4],
               [0.4, 0.4, 0.4]]])

# these two loops i and j are very inefficient 
for i in range(a.shape[1]):
    for j in range(a.shape[2]):
        print(i, j)
        aij = a[:, i, j]
        bij = b[:, i, j]
        mask = aij <= bij
        split_indices = np.where(mask)[0]
        for subarray in np.split(aij, split_indices + 1):
            if len(subarray) > 3:
                print(subarray[:-1])
将numpy导入为np
a=np.数组([[0.57337127,0.7626088,0.26965987],
[0.66987041, 0.2914202, 0.62678441]],
[[0.97442524, 0.61656519, 0.10544983],
[0.05780219, 0.00381356, 0.57118615]],
[[0.47069657, 0.36802822, 0.67483419],
[0.32773146, 0.99773064, 0.56042508]],
[[0.70984651, 0.25093198, 0.71911127],
[0.05182876, 0.9463291, 0.7222756]],
[[0.56736192, 0.62692889, 0.33814278],
[0.72362855, 0.12885637, 0.44096788]],
[[0.12706838, 0.90640269, 0.5126569],
[0.62920448, 0.24502599, 0.26754067]]])
b=np.数组([[0.4,0.4,0.4],
[0.4, 0.4, 0.4]],
[[0.4, 0.4, 0.4],
[0.4, 0.4, 0.4]],
[[0.4, 0.4, 0.4],
[0.4, 0.4, 0.4]],
[[0.4, 0.4, 0.4],
[0.4, 0.4, 0.4]],
[[0.4, 0.4, 0.4],
[0.4, 0.4, 0.4]],
[[0.4, 0.4, 0.4],
[0.4, 0.4, 0.4]]])
#这两个循环i和j的效率非常低
对于范围内的i(a.形状[1]):
对于范围内的j(a.形状[2]):
打印(i,j)
aij=a[:,i,j]
bij=b[:,i,j]
掩码=aij 3:
打印(子阵列[:-1])
现在,这是可行的然而,我的实际数据(数组a和b)的形状是(5008001500),这意味着循环变得有问题(相当昂贵)


你能想出一个更矢量化它的方法吗?我试着得到一个3D蒙版并进行3D分割,但这会导致沿轴1和轴2的分割大小不相等,这是一个问题(这就是为什么np.split只使用0或一维索引列表的原因。

而不是在轴上循环
(1,2)
,您可以循环通过轴
0
,以迭代方式检查掩码是否适用于连续元素。根据您最终想要实现的具体目标,最多需要
n
次迭代(其中
n
是您拥有的最长序列)

例如,如果您只想识别沿
轴=0
的至少3个连续元素的任何有效序列中满足
掩码
要求的起始元素,您可以执行以下操作:

mask = a > b
runs = np.zeros_like(mask, dtype=bool)
runs[:-2] = mask[:-2] & mask[1:-1] & mask[2:]
在您的示例中,这将产生:

>>> runs
array([[[ True, False, False],
    [False, False,  True]],
   [[ True, False, False],
    [False, False,  True]],
   [[ True, False, False],
    [False, False,  True]],
   [[False, False, False],
    [False, False, False]],
   [[False, False, False],
    [False, False, False]],
   [[False, False, False],
    [False, False, False]]])

在这里,
运行
对长度至少为3的有效序列的所有起始元素求值为
True
。因为我不确定一旦识别它们,您想做什么,我就到此为止。但希望从这里开始,对于您试图做的任何事情,都能清楚地概括出方法。

数组b始终只是一个th的数组吗每个位置都有相同的常数,还是为了这个例子?我想到的一个想法是减去两个切片,然后使用np。在哪里将负值的条目设置为零,然后将其作为掩码。不过我不知道如何实现。b在这里作为常数给出是为了“便于阅读”但最终是可变的。我可以很容易地得到一个3D蒙版,但我不知道如何使用3D蒙版在轴上找到连续的“真”序列(可变长度)。也就是说,np.split函数需要一个0或1-D索引数组,我想不出一种方法来给出它(或类似的向量化函数)虽然你的评论让我觉得,把切片放在循环中本身并不是很有效,我可以把它移到循环的外面,得到3D蒙版,然后把蒙版本身切片到循环中。这不是一个突破性的收获,但在lea方面仍然有一点进步这是一个非常聪明的方法。我用这个原则来适应我的需要(我的非优化解决方案需要几个月才能运行,所以我很有动力)。