如何在2D numpy数组中居中非零值?

时间:2018-08-06 23:39:01

标签: python arrays python-3.x numpy

我想在2D numpy数组中定位所有非零值,然后移动它们以使图像居中。我不想填充数组,因为我需要保持相同的形状。例如:

my_array = np.array([[1, 1, 0, 0], [0, 0, 2, 4], [0, 0, 0, 0], [0, 0, 0, 0]])
# center...

>>> [[0 0 0 0]
     [0 1 1 0]
     [0 2 4 0]
     [0 0 0 0]]

但是实际上,我需要居中的数组要大得多(例如200x200、403x403等,它们都是正方形的)。我认为np.nonzeronp.roll可能会派上用场,但不确定将它们用于大型数组的最佳方法。

1 个答案:

答案 0 :(得分:0)

nonzeroroll的组合可用于此目的。例如,如果在下面所示的循环中k=0,则np.any将标识不完全相同的零行。记录第一行和最后一行,并计算沿轴的偏移,以便在偏移之后,(first+last)/2将移至数组的中间行。然后对列执行相同的操作。

import numpy as np
my_array = np.array([[1, 1, 0, 0], [2, 4, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
print(my_array)   # before
for k in range(2):
    nonempty = np.nonzero(np.any(my_array, axis=1-k))[0]
    first, last = nonempty.min(), nonempty.max()
    shift = (my_array.shape[k] - first - last)//2
    my_array = np.roll(my_array, shift, axis=k)
print(my_array)   # after

之前:

[[1 1 0 0]
 [2 4 0 0]
 [0 0 0 0]
 [0 0 0 0]]

之后:

[[0 0 0 0]
 [0 1 1 0]
 [0 2 4 0]
 [0 0 0 0]]

替代方法:可以使用np.count_nonzeros代替np.any,这可以潜在地为被认为“足够”以限定一行作为非零像素一部分的非零像素数目设置一些阈值。图片。