ndarrays的条件过滤

Posted

技术标签:

【中文标题】ndarrays的条件过滤【英文标题】:Conditional filtering of ndarrays 【发布时间】:2020-12-03 17:43:43 【问题描述】:

假设我有以下数组:

Input = np.array([[[[17.63,  0.  , -0.71, 29.03],
         [17.63, -0.09,  0.71, 56.12],
         [ 0.17,  1.24, -2.04, 18.49],
         [ 1.41, -0.8 ,  0.51, 11.85],
         [ 0.61, -0.29,  0.15, 36.75]]],


       [[[ 0.32, -0.14,  0.39, 24.52],
         [ 0.18,  0.25, -0.38, 18.08],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.43,  0.  ,  0.3 ,  0.  ]]],


       [[[ 0.75, -0.38,  0.65, 19.51],
         [ 0.37,  0.27,  0.52, 24.27],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.  ,  0.  ,  0.  ,  0.  ]]]])

Input.shape
(3, 1, 5, 4)

加上这个Input数组是所有输入对应的Label数组,所以:

Label = np.array([0, 1, 2])

Label.shape
(3,)

我需要一些方法来检查 Input 的所有嵌套数组,以仅选择具有足够数据点的数组。

我的意思是我想要一种方法来消除(或者我应该说删除)最后 3 行的条目全为零的所有数组。在执行此操作的同时,消除该数组对应的Label

预期输出:

Input_filtered
array([[[[17.63,  0.  , -0.71, 29.03],
         [17.63, -0.09,  0.71, 56.12],
         [ 0.17,  1.24, -2.04, 18.49],
         [ 1.41, -0.8 ,  0.51, 11.85],
         [ 0.61, -0.29,  0.15, 36.75]]],


       [[[ 0.32, -0.14,  0.39, 24.52],
         [ 0.18,  0.25, -0.38, 18.08],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 0.43,  0.  ,  0.3 ,  0.  ]]]])

Label_filtered
array([0, 1])

我需要什么技巧?

【问题讨论】:

【参考方案1】:

您应该只能使用矢量化的 numpy 命令来执行此操作。

filter_ = np.any(Input[:, :, -3:], axis=(1, 2, 3))
labels_filtered = Label[filter_]
inputs_filtered = Input[[filter_]]

对于您提供的示例集,每个循环产生 4.95 µs ± 9.69 ns(每个循环 100000 个循环),而 anon01 的解决方案每个循环产生 17.1 µs ± 111 ns(每个循环 100000 个循环)。改进应该让我在更大的阵列上更加引人注目。

如果您的数据具有不同的维度,您可以更改轴参数。 对于任意数量的轴,它可能如下所示:

filter_ = np.any(Input[:, :, -3:], axis=tuple(range(1, Input.ndim)))

【讨论】:

击败我 :)。对于 OP,随着 N_subarrays 变大,这可能会明显更快。注意:不建议覆盖filter【参考方案2】:

执行此操作的最佳方法取决于您的数据规模。如果子数组很少(数千个或更少),您可以生成应用于标签和输入数组的过滤器列表:

filter = []
for j in range(len(Input)):
    arr = Input[j,:,-3:]
    filter.append(np.any(arr))
Label_filtered = Label[filter]
Input_filtered = Input[[filter]]

需要注意的几点:矢量化/numpy 位(Input[j,:,-3]np.any(arr)非常快,而原生 python 迭代和列表使用(for j in rangefilter.append ) 非常非常慢。

【讨论】:

以上是关于ndarrays的条件过滤的主要内容,如果未能解决你的问题,请参考以下文章

iptables 过滤条件(Matches)

使用grep命令怎么过滤多个条件

如何根据多个条件过滤列表?

使用或条件过滤django [重复]

awk 条件过滤

doamin 过滤条件