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

9

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
  • 258,645
  • 67
  • 583
  • 455
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
  • 15
  • 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