I've seen this post and want to do something similar, but not exactly the same.
I am implementing a little game of life game and using numpy arrays
for representing the states of the game. So I need to check, how many alive neighbors a cell has. I already got a function for getting a window of neighbors given a coordinate and row count and column count for the window size that I want to have.
So usually my windows will be of 3x3 size like this:
T = True
F = False
[[T,T,T],
[F,T,T],
[F,F,F]] # some random truth values
In this representation True
stands for a cell being alive.
Now I wrote some code iterating over all cells of the state, counting the True values and so on using a double for loop, but I think there is probably a better numpy solution.
What I'd do in the naive approach:
- iterate over all cells of the state (not only the window) (I'd like to formulate some code to to be executed if a cell meets a criteria or another (being alive and surviving or being dead and coming alive))
- get the window (wrapping or not wrapping) (function for that I already have)
- check if the current cell is alive (could just do a lookup in the state's numpy array)
- if it is alive start with an alive neighbors count of -1 otherwise start with 0
- count all True values of the window (
np.sum
) and add it to the alive neighbors count (which is -1 if the cell itself was alive, so that I only count neighbors but not the cell itself) - depending on whether the count of alive neighbors is in certain ranges (configurable), write in another (new) state's array
True
values. (I'd start out with an array, which I created using:np.full((height, width), False, dtype=bool)
) - go on with that new array, keeping the old one in a list for history or logging purposes
Basically:
if cell meets criteria:
write True at the cell's position in a new array
However meeting the criteria depends on multiple rows, because the state's numpy array is a 2D array. That's why I think the linked post is close but not exactly what I need.
How can I do this in an efficient numpy-y way, avoiding unnecessary looping?
Clarification
I am searching for the best way of implementing this in python using numpy and scipy, which aims to be very readable and has good performance.