0

Lets assume I have the following array

import numpy as np

a = np.array([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 1. 1. 0. 0. 0.]
 [0. 0. 0. 0. 1. 1. 1. 0. 0. 0.]
 [0. 0. 0. 0. 1. 1. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]])

and want to get the center of each block of ones, so that I can get the following array:

a_centers = np.array([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]])

I already thought about using means or convolutions, but I couldn't think of a really simple solution.

One in efficient solution that I found is:

a_centers = np.zeros(a.shape)

for i in range(len(a)):
    for j in range(len(a[i])):
        if np.sum(a[i - 1:i + 2, j - 1:j + 2]) == 9:
            a_centers[i, j] = 1
DΦC__WTF
  • 105
  • 1
  • 9

2 Answers2

1

if you're sure your blocks are square and don't share cells, then you can skip all the sum stuff. and i do hope that np.where is faster than for loops

x,y=np.where(a==1)
blocks=list(zip(x,y))
for _ in range(x.size//9):
    left_x,left_y=blocks[0]
    a_centers[left_x+1, left_y+1]=1
    for i in range(3):
        for j in range(3):
            blocks.remove((left_x+i, left_y+j))
diggusbickus
  • 1,537
  • 3
  • 7
  • 15
0

This is a little less inefficient, since no edge cell can be at the center of a 3x3 block:

for i in range(1,len(a)-1):
    for j in range(1,len(a[i])-1):
        if np.sum(a[i - 1:i + 2, j - 1:j + 2]) == 9:
            a_centers[i, j] = 1
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101