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 range
、filter.append
) 非常非常慢。
【讨论】:
以上是关于ndarrays的条件过滤的主要内容,如果未能解决你的问题,请参考以下文章