Shifting and adding to an array by along and across step intervals

110 views Asked by At

I would like to create a loop that shifts an array across, for this example, 3 steps, while adding a value of 1 during each shift. After 3 across shifts a new row is introduced with a starting value of 1, and the previous row stops accumulating. Then on the fifth across step, there should be a shift by one entire row, and the pattern of accumulation should repeat.

import numpy as np

def update_array(arr, y, x, shifts):
    arr[y, x] = 1
    across=5
    
    for n in range(1, shifts + 1):
        arr[y, x + n] += n * arr[y, x] + 1
        

        if n == across - 2:
            arr[y - 1, x + n] = arr[y, x]
            arr[y, x + n] = arr[y, x + n - 1]

        if n == across - 1:
            arr[y - 1, x + n] = arr[y, x] + 1
            arr[y, x + n] = arr[y, x + n - 1]

        if n == across:
            arr[y - 1, x + n] = arr[y, x + n - 1] + 1
            arr[y - 2, x + n] = arr[y - 1, x + n - 1]
            arr[y, x + n] = 0

        if n == across + 1:
            arr[y - 1, x + n] = arr[y-1, x + n - 1] + 1
            arr[y - 2, x + n] = arr[y - 2, x + n - 1]
            arr[y, x + n] = 0

        if n == across + 2:
            arr[y - 1, x + n] = arr[y-1, x + n - 1] + 1
            arr[y - 2, x + n] = arr[y - 2, x + n - 1]
            arr[y, x + n] = 0

        if n == across + 3:
            arr[y - 1, x + n] = arr[y-1, x + n - 1] 
            arr[y - 2, x + n] = arr[y - 2, x + n - 1] + 1
            arr[y, x + n] = 0   

        if n == across + 4:
            arr[y - 1, x + n] = arr[y-1, x + n - 1] 
            arr[y - 2, x + n] = arr[y - 2, x + n - 1] + 1
            arr[y, x + n] = 0 

        if n == across + 5:
            arr[y - 2, x + n] = arr[y-1, x + n - 1] + 1
            arr[y - 3, x + n] = arr[y - 2, x + n - 1] 
            arr[y, x + n] = 0 

        if n == across + 6:
            arr[y - 2, x + n] = arr[y-2, x + n - 1] + 1
            arr[y - 3, x + n] = arr[y - 3, x + n - 1] 
            arr[y, x + n] = 0

        if n == across + 7:
            arr[y - 2, x + n] = arr[y-2, x + n - 1] + 1
            arr[y - 3, x + n] = arr[y - 3, x + n - 1] 
            arr[y, x + n] = 0

        if n == across + 8:
            arr[y - 2, x + n] = arr[y-2, x + n - 1] 
            arr[y - 3, x + n] = arr[y - 3, x + n - 1] +1
            arr[y, x + n] = 0   

        if n == across + 9:
            arr[y - 2, x + n] = arr[y-2, x + n - 1] 
            arr[y - 3, x + n] = arr[y - 3, x + n - 1] + 1
            arr[y, x + n] = 0 

        if n == across + 10:
            arr[y - 3, x + n] = arr[y-2, x + n - 1] + 1
            arr[y - 4, x + n] = arr[y - 3, x + n - 1] 
            arr[y, x + n] = 0 


    return arr

# Define multiple starting positions
starting_positions = [(15, 3), (10, 5), (5, 8)]

# Initialize array
arr = np.zeros((20, 20), int)

# Update array for each starting position
for y, x in starting_positions:
    arr = update_array(arr, y, x, shifts=11)

# Print the updated array
print(arr)

This is not an efficient way of handling this problem, and would like some feedback on how to achieve this pattern; perhaps by updating the column positions/values after every across shift, and introducing a row shift in a better way?

The final array should look something like this after 14 shifts:


 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 5 6 0 0]
 [0 0 0 0 0 0 0 0 2 2 2 3 4 7 8 9 9 9 0 0]
 [0 0 0 0 0 0 1 2 4 5 6 6 6 0 0 0 0 0 0 0]
 [0 0 0 1 2 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

Or with matplotlib.pyplot.imshow

Here there are 3 initial points, and the streaking effect is applied to each

I have tried to use a pandas dataFrame, .iloc, .at, and numpy.roll, but the effects were undesirable.

Now my solution only takes into account a specific row and column position, but I eventually need it to include arbitrary and multiple locations all producing a similar pattern.

Cheers!

0

There are 0 answers