2

Short version I want to manipulate a numpy array (test, see first code snippet), so that it becomes rearranged (evenodd_single_column, see second code snippet). I wrote a for loop, but since I'm working with semi-big data I would be glad if there is a better way to achieve this.

Long version I am writing a script where at one point I should be doing the following manipulation on a numpy array:

test = np.arange(24).reshape(8,3)
test
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17],
       [18, 19, 20],
       [21, 22, 23]])

needs to be converted to an array which takes the first x (timepoints, in this example 2) from all the columns (experiments, here 3) and puts it in an array. Then it goes to the next two values of all the columns and appends the array, until all iterations (y) are over. In the end it should look like that:

>>> evenodd_single_column 
array([[ 0,  3],
       [ 1,  4],
       [ 2,  5],
       [12, 15],
       [13, 16],
       [14, 17],
       [ 6,  9],
       [ 7, 10],
       [ 8, 11],
       [18, 21],
       [19, 22],
       [20, 23]])

To achieve this, I had to write a for loop:

all_odd = []
all_even = []

x = 2
y = 4

test = np.arange(24).reshape(8,3)
counter = 0
for i in range(1, int(test.shape[0]/2)+1):
    time_window = i * x
    if math.modf(counter / 2)[0] == 0:
        for j in range(0, test.shape[1]):
            all_even.extend(test[time_window - x:time_window, j])
    else:
        for j in range(0,test.shape[1]):
            all_odd.extend(test[time_window - x:time_window, j])
    counter = counter + 1
even_single_column_test = np.asarray(all_even).reshape((int(y / 2 * test.shape[1]), x))
odd_single_column_test = np.asarray(all_odd).reshape((int(y / 2 * test.shape[1]), x))

evenodd_single_column = even_single_column_test
evenodd_single_column = np.append(evenodd_single_column, odd_single_column_test).reshape(int(odd_single_column_test.shape[0]*2), x)

My question: Can this be done with one of the elegant (and more importantly - faster) numpy matrix manipulations? I don't want to go around loops, making lists to then transform them to numpy arrays again.

I am not a programmer by training, I apologize in advance if the solution is an obvious one!

Thanks!

2
  • Answer from Divakar did it! For future reference for people on my level of programming :) test.reshape(number of times you split the data, number of times you run through the columns divided by 2, number of datapoints taken from each column at an instance, total number of initial columns), rest stays the same. Or as in initial example: test.reshape(2,y/2,x,test.shape[1]).transpose(1,0,3,2).reshape(-1,2) Commented Feb 24, 2016 at 12:48
  • Wonderful explanation there, thanks! :) The way I explain all of that to myself on such manipulation related problems is with 3 steps : Split, Align dims to make them adjacent when linearly indexed, reshape to expected format. Commented Feb 24, 2016 at 13:34

1 Answer 1

3

You can use a combination of np.reshape and np.transpose -

test.reshape(2,2,2,3).transpose(1,0,3,2).reshape(-1,2)

Sample run -

In [42]: test
Out[42]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17],
       [18, 19, 20],
       [21, 22, 23]])

In [43]: test.reshape(2,2,2,3).transpose(1,0,3,2).reshape(-1,2)
Out[43]: 
array([[ 0,  3],
       [ 1,  4],
       [ 2,  5],
       [12, 15],
       [13, 16],
       [14, 17],
       [ 6,  9],
       [ 7, 10],
       [ 8, 11],
       [18, 21],
       [19, 22],
       [20, 23]])
Sign up to request clarification or add additional context in comments.

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.