2

I have a numpy array that looks like this:

The size can be changed by altering the 'row_num' and 'col_num' variables

[[0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]]

During the program, the array may look like this:

[[0. 0. 0. 0. 0. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 1. 0. 1. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 2. 0. 2. 0. 0.]
 [2. 2. 0. 0. 0. 0. 0.]
 [1. 1. 0. 0. 0. 1. 0.]]

I am trying to make a function to move number down the bottom, like gravity. So once the function has run, the array would look like:

[[0. 0. 0. 0. 0. 0. 0.]
 [2. 2. 0. 0. 0. 0. 0.]
 [1. 1. 0. 0. 0. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 1. 0. 1. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 2. 0. 2. 1. 0.]]

Currently, the code inside my function looks like:

    for cols in range(col_num):
    for rows in range(row_num-1):

        if board[rows][cols] == 0 and board[rows+1][cols] == 1:
            board[rows+1][cols] = 0
            board[rows][cols] = 1
            print('move down 1')
        elif board[rows][cols] == 0 and board[rows+1][cols] == 2:
            board[rows+1][cols] = 0
            board[rows][cols] = 2
            print('move down 2')

The print statements are working so the condition is being met, but it does not change the array

3 Answers 3

2

One way to achieve your desired out is to use python's builtin sort method.

In [2]: data
Out[2]:
array([[0., 0., 0., 0., 0., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 1., 0., 1., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 2., 0., 2., 0., 0.],
       [2., 2., 0., 0., 0., 0., 0.],
       [1., 1., 0., 0., 0., 1., 0.]])

In [3]: np.array([sorted(column, key=bool) for column in data.T]).T
Out[3]:
array([[0., 0., 0., 0., 0., 0., 0.],
       [2., 2., 0., 0., 0., 0., 0.],
       [1., 1., 0., 0., 0., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 1., 0., 1., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 2., 0., 2., 1., 0.]])

This sorts every "non-zero" element after all "zeros".

Sign up to request clarification or add additional context in comments.

Comments

0

You could follow this approach:

import numpy as np
import pandas as pd

arr = np.array([[0., 0., 0., 0., 0., 0.,0.],
 [2.,2.,2.,0.,2.,0.,0.],
 [1.,1.,1.,0.,1.,0.,0.],
 [2.,2.,2.,0.,2.,0.,0.],
 [1.,1.,2.,0.,2.,0.,0.],
 [2.,2.,0.,0.,0.,0.,0.],
 [1.,1.,0.,0.,0.,1.,0.]])
 
arr_t = np.array(list(zip(*arr)))
print(np.array(list(zip(*[np.concatenate([line[line == 0], line[line =! 0]]) for line in arr_t]))))

OUTPUT

[[0. 0. 0. 0. 0. 0. 0.]
 [2. 2. 0. 0. 0. 0. 0.]
 [1. 1. 0. 0. 0. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 1. 0. 1. 0. 0.]
 [2. 2. 2. 0. 2. 0. 0.]
 [1. 1. 2. 0. 2. 1. 0.]]

You transpose the bidimensional array, for each line you build an array where you concatenate the array of 0s to all the other numbers, and at the end to re transpose it

Comments

0

We can use argsort to get indices that would sort the given array in such a way that numbers would align to bottom, then use np.take_along_axis to sort the array using the indices

i = (arr != 0).argsort(axis=0)
np.take_along_axis(arr, i, axis=0)

array([[0., 0., 0., 0., 0., 0., 0.],
       [2., 2., 0., 0., 0., 0., 0.],
       [1., 1., 0., 0., 0., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 1., 0., 1., 0., 0.],
       [2., 2., 2., 0., 2., 0., 0.],
       [1., 1., 2., 0., 2., 1., 0.]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.