I need to generate the following adjacency matrices:
No of Nodes = 3
A B C AB AC BC
A 0 1 1 0 0 1
B 1 0 1 0 1 0
C 1 1 0 1 0 0
AB 0 0 1 0 0 0
AC 0 1 0 0 0 0
BC 1 0 0 0 0 0
To generate an adjacency matrix for 3 nodes, I can use the code available here, which is
out = np.block([
[1 - np.eye(3), np.eye(3) ],
[ np.eye(3), np.zeros((3, 3))]
]).astype(int)
But it cannot use for different number of nodes, for example if we have 5 nodes then:
No of Nodes = 5
A B C D E AB AC AD AE BC BD BE CD CE DE
A 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1
B 1 0 1 1 1 0 1 1 1 0 0 0 1 1 1
C 1 1 0 1 1 1 0 1 1 0 1 1 0 0 1
D 1 1 1 0 1 1 1 0 1 1 0 1 0 1 0
E 1 1 1 1 0 1 1 1 0 1 1 0 1 0 0
AB 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
AC 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0
AD 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0
AE 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0
BC 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0
BD 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0
BE 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0
CD 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0
CE 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0
DE 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
Is there any simple and easiest way to implement these adjacency matrices?
Inferring the logic of the output from your two examples, I think something like this might do what you want:
import numpy as np
def make_matrix(N, dtype=int):
n_comb = N * (N - 1) // 2
upper_left = 1 - np.eye(N, dtype=dtype)
lower_right = np.zeros((n_comb, n_comb), dtype=dtype)
cross = np.ones((N, N, N), dtype=dtype)
i = np.arange(N)
cross[i, :, i] = 0
cross[:, i, i] = 0
cross = cross[(np.triu_indices(N, k=1))]
return np.block([[upper_left, cross.T],
[cross, lower_right]])
print(make_matrix(3))
[[0 1 1 0 0 1]
[1 0 1 0 1 0]
[1 1 0 1 0 0]
[0 0 1 0 0 0]
[0 1 0 0 0 0]
[1 0 0 0 0 0]]
print(make_matrix(5))
[[0 1 1 1 1 0 0 0 0 1 1 1 1 1 1]
[1 0 1 1 1 0 1 1 1 0 0 0 1 1 1]
[1 1 0 1 1 1 0 1 1 0 1 1 0 0 1]
[1 1 1 0 1 1 1 0 1 1 0 1 0 1 0]
[1 1 1 1 0 1 1 1 0 1 1 0 1 0 0]
[0 0 1 1 1 0 0 0 0 0 0 0 0 0 0]
[0 1 0 1 1 0 0 0 0 0 0 0 0 0 0]
[0 1 1 0 1 0 0 0 0 0 0 0 0 0 0]
[0 1 1 1 0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 1 1 0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 1 0 0 0 0 0 0 0 0 0 0]
[1 0 1 1 0 0 0 0 0 0 0 0 0 0 0]
[1 1 0 0 1 0 0 0 0 0 0 0 0 0 0]
[1 1 0 1 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 0 0 0 0 0 0 0 0 0 0 0 0]]
The logic here is that each row of the upper-right matrix is like the flattened upper-triangle of a straightforward NxN matrix. For example:
# construct second row of upper-right matrix for 5x5 case:
x = np.ones((5, 5), dtype=int)
x[1] = 0
x[:, 1] = 0
print(x)
# [[1 0 1 1 1]
# [0 0 0 0 0]
# [1 0 1 1 1]
# [1 0 1 1 1]
# [1 0 1 1 1]]
print(x[np.triu_indices(5, k=1)])
# [0 1 1 1 0 0 0 1 1 1]
Related
I am trying to make a square path of a specified length:
I made a function - and if I put 20 then I get a 6x6 matrix.
How can I add a margin of 0's of eg. 3 fields thickness?
like this
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 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 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 0 0
0 0 0 0 0 0 0 0 0 0 0 0
def square(length): return [
[1 for _ in range(length//4+1)]
for _ in range(length//4+1)
]
for x in square(24):
print(x)
You can prepare a line pattern of 0s and 1s then build a 2D matrix by intersecting them.
def square(size,margin=3):
p = [0]*margin + [1]*(size-2*margin) + [0]*margin
return [[r*c for r in p] for c in p]
for row in square(20):print(*row)
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 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 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 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
Here's one way. One caution here is that, because of the way I duplicated the zero rows, those are all the same list. If you modify one of the zero rows, it will modify all of them.
def square(length):
zeros = [0]*(length//4+7)
sq = [zeros] * 3
sq.extend( [
([0,0,0] + [1 for _ in range(length//4+1)] + [0,0,0] )
for _ in range(length//4+1)
])
sq.extend( [zeros]*3 )
return sq
for x in square(24):
print(x)
Here's a numpy method.
import numpy as np
def square(length):
c = length//4+1
sq = np.zeros((c+6,c+6)).astype(int)
sq[3:c+3,3:c+3] = np.ones((c,c))
return sq
print( square(24) )
One way to do this is to build it as a flat string, then use textwrap to style the output into the right number of lines:
import textwrap
# The number of 1's in a row/column
count = 6
# The number of 0's to pad with
margin = 3
# The total 'size' of a row/column
size = margin + count + margin
pad_rows = "0" * size * margin
core = (("0" * margin) + ("1" * count) + ("0" * margin)) * count
print('\n'.join(textwrap.wrap(pad_rows + core + pad_rows, size)))
I would like to do something similar to this question, or this other one, but using periodic boundary conditions (wrapping). I'll make a quick example.
Let's say I have the following numpy 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 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 0
0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0
0 0 1 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 0 0
0 0 0 0 0 0 0 0 0 0 0
Then, by using one of the methods proposed in the two linked questions, I am able to extract the bounding box of non-zero values:
0 0 0 1 1 1 1 1
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
1 1 1 1 0 0 0 0
However, if the non-zero elements "cross" the border and come back on the other side, like so:
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 1 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 1 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 0 0 0 0 0 0 0 0 0 0
Then the result is:
1 1 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 1 1 1 1 0 0
which is not what I want. I would like the result to be the same as the previous case. I am trying to figure out an intelligent way to do this, but I am stuck. Anybody have ideas?
We can adapt this answer like so:
import numpy as np
def wrapped_bbox(a):
dims = [*range(1,a.ndim)]
bb = np.empty((a.ndim,2),int)
i = 0
while True:
n = a.shape[i]
r = np.arange(1,2*n+1)
ai = np.any(a,axis=tuple(dims))
r1_a = np.where(ai,r.reshape(2,n),0).ravel()
aux = np.maximum.accumulate(r1_a)
aux = r-aux
idx = aux.argmax()
mx = aux[idx]
if mx > n:
bb[i] = 0,n
else:
bb[i] = idx+1, idx+1 - mx
if bb[i,0] >= n:
bb[i,0] -= n
elif bb[i,1] == 0:
bb[i,1] = n
if i == len(dims):
return bb
dims[i] -= 1
i += 1
# example
x = """
......
.x...-
..x...
.....x
"""
x = np.array(x.strip().split())[:,None].view("U1")
x = (x == 'x').view('u1')
print(x)
for r in range(x.shape[1]):
print(wrapped_bbox(np.roll(x,r,axis=1)))
Run:
[[0 0 0 0 0 0] # x
[0 1 0 0 0 0]
[0 0 1 0 0 0]
[0 0 0 0 0 1]]
[[1 4] # bbox vert
[5 3]] # bbox horz, note wraparound (left > right)
[[1 4]
[0 4]] # roll by 1
[[1 4]
[1 5]] # roll by 2
[[1 4]
[2 6]] # etc.
[[1 4]
[3 1]]
[[1 4]
[4 2]]
Short version: I would like to use the values in a 2D array to index the third dimension of a corresponding subset of a larger array - and then increment those elements.
I would appreciate help making the two incorporate_votes algorithms quicker. Actually sliding the classifier over the array and calculating optimal strides is not the point here.
Long version:
I have an algorithm, which classifies each element in R1xC1 2D array as 1 of N classes.
I would like to classify a larger 2D array of size R2xC2. Rather than tessellating the larger array into multiple R1xC1 2D arrays I would like to slide the classifier over the larger array, such that each element in the larger array is classified multiple times. This means that I will have a R2xC2xN array to store the results in, and as the window slides across the large array each pixel in the window will increment one of elements in third dimension (i.e. one of the N classes).
After all the sliding is finished we can simply get the argmax in the dimension corresponding to the classification to get the per element classification.
I intend to scale this up to classify an array of several million pixels with a few dozens so I am concerned with the efficiency of using the classification results to increment one value in the classification dimension per element.
Below is the toy version of the problem I have been crafting all evening in Python3. It has a naive double for loop implementation and a slightly better one obtained by index swizzling and some smart indexing. The classifier is just random.
import numpy as np
map_rows = 8
map_cols = 10
num_candidates = 3
vote_rows = 6
vote_cols = 5
def display_tally(the_tally):
print("{:25s}{:25s}{:25s}".format("Class 0", "Class 1", "Class 2"))
for i in range(map_rows):
for k in range(num_candidates):
for j in range(map_cols):
print("{:<2}".format(the_tally[i, j, k]), end='')
print(" ", end='')
print("")
def incorporate_votes(current_tally, this_vote, left, top):
for i in range(vote_rows):
for j in range(vote_cols):
current_tally[top + i, left + j, this_vote[i, j]] += 1
return current_tally
def incorporate_votes2(current_tally, this_vote, left, top):
for i in range(num_candidates):
current_tally[i, top:top + vote_rows, left:left + vote_cols][this_vote == i] += 1
return current_tally
tally = np.zeros((map_rows, map_cols, num_candidates), dtype=int)
swizzled_tally = np.zeros((num_candidates, map_rows, map_cols), dtype=int)
print("Before voting")
display_tally(tally)
print("\n Votes from classifier A (centered at (2,2))")
votes = np.random.randint(num_candidates, size=vote_rows*vote_cols).reshape((vote_rows, vote_cols))
print(votes)
tally = incorporate_votes(tally, votes, 0, 0)
swizzled_tally = incorporate_votes2(swizzled_tally, votes, 0, 0)
print("\nAfter classifier A voting (centered at (2,2))")
display_tally(tally)
print("\n Votes from classifier B (Centered at (5, 4))")
votes2 = np.random.randint(num_candidates, size=vote_rows*vote_cols).reshape((vote_rows, vote_cols))
print(votes2)
tally = incorporate_votes(tally, votes2, 3, 2)
swizzled_tally = incorporate_votes2(swizzled_tally, votes2, 3, 2)
print("\nAfter classifier B voting (Centered at (5, 4))")
print("Naive vote counting")
display_tally(tally)
print("\nSwizzled vote counting")
display_tally(np.moveaxis(swizzled_tally, [-2, -1], [0, 1]))
new_tally = np.moveaxis(tally, -1, 0)
classifications = np.argmax(swizzled_tally, axis=0)
print("\nNaive classifications")
print(classifications)
print("\nSwizzled classifications")
classifications = np.argmax(tally, axis=2)
print(classifications)
And some sample output:
Before voting
Class 0 Class 1 Class 2
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 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 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 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 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 0 0 0 0 0
Votes from classifier A (centered at (2,2))
[[1 1 2 2 1]
[0 2 0 2 1]
[0 2 2 0 2]
[1 1 1 2 0]
[1 0 0 2 1]
[2 1 1 1 0]]
After classifier A voting (centered at (2,2))
Class 0 Class 1 Class 2
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 1 1 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Votes from classifier B (Centered at (5, 4))
[[2 2 2 0 0]
[0 1 2 1 2]
[2 0 0 2 0]
[2 2 1 1 1]
[1 2 0 2 1]
[1 1 1 1 2]]
After classifier B voting (Centered at (5, 4))
Naive vote counting
Class 0 Class 1 Class 2
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0
0 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0
Swizzled vote counting
Class 0 Class 1 Class 2
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0
0 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0
Naive classifications
[[1 1 2 2 1 0 0 0 0 0]
[0 2 0 2 1 0 0 0 0 0]
[0 2 2 0 2 2 0 0 0 0]
[1 1 1 0 0 2 1 2 0 0]
[1 0 0 2 0 0 2 0 0 0]
[2 1 1 1 0 1 1 1 0 0]
[0 0 0 1 2 0 2 1 0 0]
[0 0 0 1 1 1 1 2 0 0]]
Swizzled classifications
[[1 1 2 2 1 0 0 0 0 0]
[0 2 0 2 1 0 0 0 0 0]
[0 2 2 0 2 2 0 0 0 0]
[1 1 1 0 0 2 1 2 0 0]
[1 0 0 2 0 0 2 0 0 0]
[2 1 1 1 0 1 1 1 0 0]
[0 0 0 1 2 0 2 1 0 0]
[0 0 0 1 1 1 1 2 0 0]]
Consider my data in a Pandas Series
s = pd.Series('1az wb58 jsui ne3'.split())
s
0 1az
1 wb58
2 jsui
3 ne3
dtype: object
I need it to look like:
1 3 5 8 a b e i j n s u w z
0 1 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0 0 0 0 0 0 1 0
2 0 0 0 0 0 0 0 1 1 0 1 1 0 0
3 0 1 0 0 0 0 1 0 0 1 0 0 0 0
However when I try:
pd.get_dummies(s)
1az jsui ne3 wb58
0 1 0 0 0
1 0 0 0 1
2 0 1 0 0
3 0 0 1 0
What is the most concise way to do this?
Maybe apply list
pd.get_dummies(s.apply(list).apply(pd.Series).stack()).sum(level=0)
Out[222]:
1 3 5 8 a b e i j n s u w z
0 1 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0 0 0 0 0 0 1 0
2 0 0 0 0 0 0 0 1 1 0 1 1 0 0
3 0 1 0 0 0 0 1 0 0 1 0 0 0 0
Or
s.apply(list).str.join(',').str.get_dummies(',')
Out[224]:
1 3 5 8 a b e i j n s u w z
0 1 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0 0 0 0 0 0 1 0
2 0 0 0 0 0 0 0 1 1 0 1 1 0 0
3 0 1 0 0 0 0 1 0 0 1 0 0 0 0
Solution with MultiLabelBinarizer and DataFrame constructor:
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df = pd.DataFrame(mlb.fit_transform(s),columns=mlb.classes_)
print (df)
1 3 5 8 a b e i j n s u w z
0 1 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0 0 0 0 0 0 1 0
2 0 0 0 0 0 0 0 1 1 0 1 1 0 0
3 0 1 0 0 0 0 1 0 0 1 0 0 0 0
Another solution - DataFrame.from_records + get_dummies, but last is necessary aggregate columns by max:
df = pd.get_dummies(pd.DataFrame.from_records(s),prefix_sep='',prefix='').max(level=0, axis=1)
print (df)
1 3 5 8 a b e i j n s u w z
0 1 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0 0 0 0 0 0 1 0
2 0 0 0 0 0 0 0 1 1 0 1 1 0 0
3 0 1 0 0 0 0 1 0 0 1 0 0 0 0
I want to check if all entries of a matrix A within 10 indices of a given entry (x,y) are zero. I think something like this should do it
(numpy.take(A,[x-10:x+10,y-10:y+10]) == 0).all()
but I'm getting a invalid syntax error. Think I'm not constructing the index ranges right, any suggestions?
Don't worry about using take, just index your array like this:
(A[x-10:x+10,y-10:y+10] == 0).all()
A simple boolean check against the entries of the submatrix will do
np.all(A[x-10:x+11,y-10:y+11]==0)
(note the upper index is not included, so I changed to i-10:i+11)
Suppose A is an array of shape (19,19):
import numpy as np
H = W = 19
x, y = 1, 1
N = 10
A = np.random.randint(10, size=(H,W))
Then
In [433]: A[x-N:x+N,y-N:y+N]
Out[433]: array([[4]])
Since x-N is 1-10 = -9, A[x-N:x+N,y-N:y+N] is equivalent to A[-9:11,-9:11],
which is equivalent to A[19-9:11,19-9:11] which is the same as A[10:11,10:11].
So only one value is selected.
That's not giving you "all entries of a matrix A within 10 indices of a given
entry (x,y)".
Instead, you could generate the desired subregion using a boolean mask:
X, Y = np.ogrid[0:H,0:W]
mask = (np.abs(X - x) < N) & (np.abs(Y - y) < N)
Once you have the mask, you can select the subregion where the mask is True using A[mask], and test if every value is zero with
(A[mask] == 0).all()
import numpy as np
np.random.seed(2015)
H = W = 19
x, y = 1, 1
N = 10
A = np.random.randint(10, size=(H,W))
print(A[x-N:x+N,y-N:y+N])
# [[4]]
X, Y = np.ogrid[0:H,0:W]
mask = (np.abs(X - x) < N) & (np.abs(Y - y) < N)
print(mask.astype(int))
# [[1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 1 1 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 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 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 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]]
print(A[mask] == 0).all()
# False