7

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.

Community
  • 1
  • 1
bturnip
  • 85
  • 1
  • 4
  • either pass the columns around and roll them before constructing `GRID` or break `GRID` back into columns, roll one, and reconstruct `GRID` – Gabriel Jul 17 '14 at 04:13

2 Answers2

10

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']]
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
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.

Abhishek Mittal
  • 356
  • 1
  • 16
  • 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. – bturnip Jul 17 '14 at 12:54
  • 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. – Abhishek Mittal Jul 17 '14 at 14:37
  • I chose Joe Kington's answer because I don't have to deconstruct and reassemble the grid. – bturnip Jul 17 '14 at 15:16