0

I'm using advanced indexing on the numpy arrays but find that my columns do not swap but instead they're replaced.

For example:

test_array = np.array([ [1, 2, 3, 4, 5] , [5, 4, 3, 2, 1] , [5, 2, 2, 2, 1] , [1, 2, 2, 1, 1] ])
zeros = np.repeat( np.zeros((1, 5)) , 2, axis=0)
swap_array = np.vstack([test_array, zeros])

swap_array[ : , [ 0 , 2 ] ] = swap_array[ : , [ -2 , -1 ] ]
print(swap_array)

#
[[0. 0. 5. 1. 0. 0.]
 [0. 0. 2. 2. 0. 0.]
 [0. 0. 2. 2. 0. 0.]
 [0. 0. 2. 1. 0. 0.]
 [0. 0. 1. 1. 0. 0.]]

What is the most effective way to swap the first-two columns with the last two, given I do not know the same of the array.

3
  • This certainly answers your question: Swap two values in a numpy array. Commented Nov 20, 2022 at 11:06
  • @JérômeRichard No, that wants to swap values and I have not having issues with swapping in general. I just find when trying to index with - instead of swapping, it replaces. Commented Nov 20, 2022 at 11:07
  • Ha Ok Indeed. I turns out this applies to the current answer though. Commented Nov 20, 2022 at 11:10

1 Answer 1

1

They are indeed replaced, because there is no assignment stating that the last two columns should contain the first two. To do this, you can use the comma operator (or tuple unpacking), which evaluates all expressions on the right-hand side, before any assignment is made. There are pitfalls with this approach, so it is not safe, in general (See comments below & thanks @Jérôme Richard).

test_array = np.array([ [1, 2, 3, 4, 5] , [5, 4, 3, 2, 1] , [5, 2, 2, 2, 1] , [1, 2, 2, 1, 1] ])
zeros = np.repeat( np.zeros((1, 5)) , 2, axis=0)
swap_array = np.vstack([test_array, zeros])
print(swap_array)

swap_array[ : , [ 0 , 2 ] ], swap_array[ : , [ -2, -1 ] ] = swap_array[ : , [ -2 , -1 ] ], swap_array[ : , [ 0 , 2 ] ]
print(swap_array)

You can do this more concisely and safely. The approach below should be preferred.

swap_array[ : , [ 0 , 2, -2, -1 ] ] = swap_array[ : , [ -2 , -1, 0, 2 ] ]

Result for both codes:

[[1. 2. 3. 4. 5.]
 [5. 4. 3. 2. 1.]
 [5. 2. 2. 2. 1.]
 [1. 2. 2. 1. 1.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

[[4. 2. 5. 1. 3.]
 [2. 4. 1. 5. 3.]
 [2. 2. 1. 5. 2.]
 [1. 2. 1. 1. 2.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
Sign up to request clarification or add additional context in comments.

4 Comments

The concise example is actually also more correct. Otherwise, there is certainly an issue with the views (see the comment in the second answer in the link in the OP question).
@JérômeRichard indeed, you are right. I'll edit the post to make this clear
What if I have a list of numpy arrays and wanted to change the positions for each array. What des this look like?
@teslajohn If you have multiple arrays and want to perform the above swap on all of them, you can loop over the list of the arrays an use the iterator with the code above. e.g. for a in list_of_arrays: a[:, [0, 2, -2, -1]] = a[:, [-2, -1, 0, 2]]

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.