gpt4 book ai didi

python - numpy 数组的 bool /非零索引循环的替代方案

转载 作者:行者123 更新时间:2023-12-01 00:36:19 25 4
gpt4 key购买 nike

我需要仅选择 3d 二进制数组的非零 3d 部分(或者 bool 数组的真实值)。目前,我可以通过一系列使用 np.any 的“for”循环来做到这一点,但这确实有效,但看起来很尴尬且缓慢,因此目前正在研究一种更直接的方法来完成该任务。

我对 numpy 相当陌生,所以我尝试过的方法包括 a) 使用 np.nonzero ,它返回我不知道如何处理我的目的的索引,b) boolean array indexing和 c) boolean masks 。我通常可以理解简单 2d 数组的每种方法,但很难理解这些方法之间的差异,并且无法让它们返回 3d 数组的正确值。

这是我当前的函数,它返回具有非零值的 3D 数组:

def real_size(arr3):
true_0 = []
true_1 = []
true_2 = []
print(f'The input array shape is: {arr3.shape}')

for zero_ in range (0, arr3.shape[0]):
if arr3[zero_].any()==True:
true_0.append(zero_)
for one_ in range (0, arr3.shape[1]):
if arr3[:,one_,:].any()==True:
true_1.append(one_)
for two_ in range (0, arr3.shape[2]):
if arr3[:,:,two_].any()==True:
true_2.append(two_)

arr4 = arr3[min(true_0):max(true_0) + 1, min(true_1):max(true_1) + 1, min(true_2):max(true_2) + 1]
print(f'The nonzero area is: {arr4.shape}')
return arr4

# Then use it on a small test array:
test_array = np.zeros([2, 3, 4], dtype = int)
test_array[0:2, 0:2, 0:2] = 1

#The function call works and prints out as expected:
non_zero = real_size(test_array)
>> The input array shape is: (2, 3, 4)
>> The nonzero area is: (2, 2, 2)

# So, the array is correct, but likely not the best way to get there:
non_zero

>> array([[[1, 1],
[1, 1]],

[[1, 1],
[1, 1]]])

代码工作正常,但我在更大、更复杂的数组上使用它,并且认为这不是一个合适的方法。任何关于更直接的方法来完成这项工作的想法将不胜感激。如果输入数组在原始数组中有两个独立的非零 3d 区域,我还担心错误和结果。

为了澄清问题,我需要将一个或多个 3D 部分作为一个或多个以原始较大数组开头的 3D 数组返回。返回的数组不应包含三维空间中任何给定外平面中的无关零(或假值)。仅获取非零值的索引(反之亦然)本身并不能解决问题。

最佳答案

假设您想要消除仅包含零的所有行、列等,您可以执行以下操作:

nz = (test_array != 0)
non_zero = test_array[nz.any(axis=(1, 2))][:, nz.any(axis=(0, 2))][:, :, nz.any(axis=(0, 1))]

使用np.nonzero的替代解决方案:

i = [np.unique(_) for _ in np.nonzero(test_array)]
non_zero = test_array[i[0]][:, i[1]][:, :, i[2]]
<小时/>

这也可以推广到任意维度,但需要更多的工作(此处仅显示第一种方法):

def real_size(arr):
nz = (arr != 0)
result = arr
axes = np.arange(arr.ndim)
for axis in range(arr.ndim):
zeros = nz.any(axis=tuple(np.delete(axes, axis)))
result = result[(slice(None),)*axis + (zeros,)]
return result

non_zero = real_size(test_array)

关于python - numpy 数组的 bool /非零索引循环的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57738936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com