8

I'm creating an 2d numpy array, with a simplified example like something like this:

COL01 = np.array(["A", "D", "G"])
COL02 = np.array(["B", "E", "H"])
COL03 = np.array(["C", "F", "I"])

GRID = np.array([[COL01], [COL02], [COL03]])

I'm passing the GRID around in my code. I want to be able to modify GRID by rolling ONLY one of the arrays that makes up its component rows. For instance, I want to pass GRID into a function with a row number and number of positions to roll, and then return the result.

How can I roll the single row independently? I tried following the answer from here: [Roll rows of a matrix independently, but I couldn't figure out how to adapt that answer to my problem.

1
  • either pass the columns around and roll them before constructing GRID or break GRID back into columns, roll one, and reconstruct GRID Commented Jul 17, 2014 at 4:13

2 Answers 2

11

You can do this by selecting the row you want to operate on and using numpy.roll.

Let's say we want to roll the first row one place to the right:

import numpy as np

grid = np.array([['A', 'D', 'G'],
                 ['B', 'E', 'H'],
                 ['C', 'F', 'I']])

grid[0] = np.roll(grid[0], 1)
print grid

This yields:

[['G' 'A' 'D']
 ['B' 'E' 'H']
 ['C' 'F' 'I']]

Notice that we're modifying the original array.

You should decide whether you want to operate on the array in-place (modifying the original) or if you want to make a copy each time. Repeated calls will have different effects depending on what you decide:

import numpy as np

def independent_roll_inplace(arr, ind, amount):
    arr[ind] = np.roll(arr[ind], amount)

def independent_roll_copy(arr, ind, amount):
    arr = arr.copy()
    arr[ind] = np.roll(arr[ind], amount)
    return arr

grid = np.array([['A', 'D', 'G'],
                 ['B', 'E', 'H'],
                 ['C', 'F', 'I']])

As an example of the difference, if we make a copy each time, we start "fresh" with the original grid. Repeated calls have no effect on the original:

print 'Roll the second row one place'
print independent_roll_copy(grid, 1, 1)
print 'Roll the second row two places'
print independent_roll_copy(grid, 1, 2)
print 'Roll the second row three places'
print independent_roll_copy(grid, 1, 3)

This yields:

Roll the second row one place
[['A' 'D' 'G']
 ['H' 'B' 'E']
 ['C' 'F' 'I']]
Roll the second row two places
[['A' 'D' 'G']
 ['E' 'H' 'B']
 ['C' 'F' 'I']]
Roll the second row three places
[['A' 'D' 'G']
 ['B' 'E' 'H']
 ['C' 'F' 'I']]

However, if we're modifying the original each time, we'd get the same result by rolling one place multiple times:

for _ in range(3):
    print 'Roll the first row one place, modifying the original'
    independent_roll_inplace(grid, 0, 1)
    print grid

Yielding:

Roll the second row one place, modifying the original
[['A' 'D' 'G']
 ['H' 'B' 'E']
 ['C' 'F' 'I']]
Roll the second row one place, modifying the original
[['A' 'D' 'G']
 ['E' 'H' 'B']
 ['C' 'F' 'I']]
Roll the second row one place, modifying the original
[['A' 'D' 'G']
 ['B' 'E' 'H']
 ['C' 'F' 'I']]
Sign up to request clarification or add additional context in comments.

Comments

0

This code might solve your problem.

REV_GRID is the rolled over version of GRID.

COL01 = ["A", "D", "G"]
COL02 = ["B", "E", "H"]
COL03 = ["C", "F", "I"]

GRID = []
GRID.append(COL01)
GRID.append(COL02)
GRID.append(COL03)

REV_GRID = []

for col in GRID:
    REV_GRID.append(col[::-1])

print GRID
print REV_GRID

Please let me know if it does not solve your problem. We will work on that.

3 Comments

Thanks for the suggestion, but this shifts the values in each of the rows. I want to be able to arbitrarily pick one of the rows and roll the values of that array only.
That can be done as well. In the above example, let say you want to roll COL02 That can be done by: COL02 = GRID[1] REV_COL02 = COL02[::-1] COL02 = ["B", "E", "H"] REV_COL02 = ["H", "E", "B"] I hope that it will solve your problem. Please let me know if I have misunderstood your problem.
I chose Joe Kington's answer because I don't have to deconstruct and reassemble the grid.

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.