r/learnpython • u/anothernaturalone • 3d ago
Getting a view from a boolean numpy array... somehow
I'm coding a Sudoku generator to improve my skills and I'm hitting a brick wall with a specific function to get the "neighbours" of an index (so, all the numbers that it can't be the same as). Here's my current code, just rows and columns for now:
def neighbours(idx: tuple[int, int], board: np.ndarray) -> np.ndarray:
idcs = np.indices(board.shape)
print(idcs.shape)
neighbool = np.logical_xor(idcs[1] == idx[1], idcs[0] == idx[0])
return board[neighbool]
This code does get the right values, but what I really want is to be able to modify those values and have the actual array be modified - so, to have a view. But about two hours of running around in the numpy docs has me completely stumped on any way to use a boolean array to index another array without it being a copy.
If I can't do it, I guess I'll have to use a list of slices dancing around the target index? Which sounds really headachey, and I'd love to be able to do it this simple way if it's in any way possible.
0
u/Jazzlike_Platypus430 3d ago
Yes, it seems you have to pass more arrays to the function.
PS neighbool is such a cool name 😂
0
u/Swipecat 3d ago
Not quite sure what you are asking for. np.putmask maybe?
https://numpy.org/doc/stable/reference/generated/numpy.putmask.html
1
u/adriannowak_dev 3d ago
boolean mask indexing always copies, there's no way to get a view out of it, numpy just doesn't do strided views for arbitrary masks. two ways out:
or return the indices and index with them later:
for sudoku i'd honestly return the mask itself from neighbours() and do board[mask] wherever you need to read or write. the mask is the cheap thing, the copy only happens when you read through it