How to center the nonzero values within 2D numpy array?

此生再无相见时 提交于 2021-02-11 12:35:04

问题


I'd like to locate all the nonzero values within a 2D numpy array and move them so that the image is centered. I do not want to pad the array because I need to keep it the same shape. For example:

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]]

But in reality the arrays I need to center are much larger (like 200x200, 403x403, etc, and they are all square). I think np.nonzero and np.roll might come in handy, but am not sure of the best way to use these for my large arrays.


回答1:


The combination of nonzero and roll can be used for this purpose. For example, if k=0 in the loop shown below, then np.any will identify the rows that are not identically zero. The first and last such rows are noted, and the shift along the axis is computed so that after the shift, (first+last)/2 will move to the middle row of the array. Then the same is done for columns.

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

Before:

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

After:

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

Alternative: np.count_nonzeros can be used in place of np.any, which allows to potentially set some threshold for the number of nonzero pixels that are deemed "enough" to qualify a row as a part of the image.



来源:https://stackoverflow.com/questions/51716954/how-to-center-the-nonzero-values-within-2d-numpy-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!