Slicing 3d Arrays - python

I want to slice 3D arrays in a way to only print the last element of each row in the 2nd array.
In my 3D Array:
np.random.seed(42)
M = np.random.randint(10, size=(2,2,10))
print(M)
I tried accessing the last elements of the 2nd Array in a way like this:
print(M[1::2]) ## which just prints me the whole 2nd Array
print(M[1::,2]) ## which gives me an error of index 2 being out of bounds
I understand the first print() method like:
1: # chose the second array
: # chose all rows of the 2nd array
:2 # chose every second index of the row and print it
strangely it prints the whole array which confuses me.
The second print() method i was hoping to at least print the 2nd index alone but I get that error message.
So I tried around more and came up with that code:
print(M[1:,0:,::2])
It gives me the result I want, but I cannot read the code.
I understand
1: ## which chooses the 2nd array
but ,0:,::2 is confusing me. ::2 is chosing every 2nd index I guess but I still don't understand when I can make ':' and when not. Or what is the meaning of ',' in the slicing process.

In numpy,the operator works as follows :- [start_index:end_index:step].
This means that when you index M[1:,0:,::2] what you are actually indexing is everything from the first index of the first dimension([1:]), then everything from the start of the second dimension([0:]), and finally every element with a step of 2 ([::2]).
The , is used to seperate the dimensions so I assume what you actually want to do is M[:,1,-1] to get the last element of every 2nd array.

Related

Replacing new vector after it gets empty on Python

Hi have an original vector, I would like to put the first 3 elements into new vector, do some math and then get new elements after the math. Put those new elements into a new vector, delete the original first 3 elements from original vector and repeat this exact procedure until the original vector is empty.
This is what I have done so far
OR=np.array([1,2,3,4,5,6])
new=OR[0:3]
while (True):
tran=-2*c_[new]
OR= delete(OR, [0,1,2])
new=OR[0:3]
if (OR==[]):
break
However it is not working out properly, do you have any suggestions?
Not sure what c_ is in your code, but regardless since numpy arrays are not dynamic, you can't remove or add elements to them. Deleting elements creates a new array without those elements, which is not optimal. I think you should either use a python deque which has fast pop methods for removing one element from the front/end, or just iterate over the original numpy array, for example like this:
def modify_array(arr):
# your code for modifying the array here
result = []
original_array = np.arange(1, 10)
for idx in range(0, len(original_array), 3):
result.append(modify_array(original_array[idx:idx+3]))
result = np.concatenate(result)

Cannot swap values in for loop in python in the first iteration

I am trying to find the minimum swaps to sort an array without duplicates in python.I have the following code and i am using the greedy approach where i sort the array and compare and swap accordingly
def minimumSwaps(arr):
totalswapcount=0
sortedarr=sorted(arr)
for x in range(0,len(arr)-1):
if (arr[x]!=sortedarr[x]):
totalswapcount+=1
arr[x],arr[arr.index(sortedarr[x])]=arr[arr.index(sortedarr[x])],arr[x]
print(totalswapcount)
minimumSwaps([2,3,4,1,5])
The code does not swap on the first iteration with this dry run for some reason.The array is repeated and hence it adds an iteration to the final result.Here is the result of this dry run
I was expecting that after the first repetition the array would become [1,3,4,2,5] where 1 and 2 is swapped since 2 occupies 1's real position but it stays the same instead
When you assign to
arr[x],arr[arr.index(sortedarr[x])]=
it calculates the subscript arr.index(sortedarr[x]) after it has already assigned to arr[x]. Get the index outside the spread assignment, so it will use the new index of the element if the element has been moved into a lower index.
if (arr[x]!=sortedarr[x]):
totalswapcount+=1
y = arr.index(sortedarr[x])
arr[x], arr[y] = arr[y], arr[x]

How do you print out elements from a Numpy array on new lines using a for loop?

Create an array with numpy and add elements to it. After you do this, print out all its elements on new lines.
I used the reshape function instead of a for loop. However, I know this would create problems in the long run if I changed my array values.
import numpy as np
a = np.array([0,5,69,5,1])
print(a.reshape(5,1))
How can I make this better? I think a for loop would be best in the long run but how would I implement it?
Some options to print an array "vertically" are:
print(a.reshape(-1, 1)) - You can pass -1 as one dimension,
meaning "expand this dimension to the needed extent".
print(np.expand_dims(a, axis=1)) - Add an extra dimension, at the second place,
so that each row will have a single item. Then print.
print(a[:, None]) - Yet another way of reshaping the array.
Or if you want to print just elements of a 1-D array in a column,
without any surrounding brackets, run just:
for x in a:
print(x)
You could do this:
print(a.reshape([a.shape[0], 1]))
This will work regardless of how many numbers are in your numpy array.
Alternatively, you could also do this:
[print(number) for number in a.tolist()]

how to extract line in images(3bands) using numpy in python?

In order to modify the value of a particular vertical line in the image, i want to extract the 3-band vertical line of the image.
When I was a two dimensional array, I extracted the vertical lines with the following code:
vertical_line = array[:,[1]]
I tried to use this code in a 3d array image but it failed.
#image shape(b,g,r) (100,100,3)
# my try
vertical_line_try_1 = image[:,[1]][3]#result => [[255,255,255]]
vertical_line_try_2 = image[:,[1][3]]#result => IndexError: list index out of range
vertical_line_try_3 = image[:,[1],[3]]#result => IndexError: index 3 is out of bounds for axis 2 with size 3
How can I extract the vertical lines of three bands at once without writing a loop?
When you index with a slice the corresponding dimension is kept (since you get a possible stridded range of values). On the other hand, when you index with a single number that dimension disappears.
Ex:
a = np.random.randn(4,5)
# Let's get the third column in the matrix
print(a[:, 2].shape) # prints `(4,)` -> we get a vector
print(a[:, 2:3].shape) # prints `(4,1)` -> we keep the result as a column matrix
From your two dimensional example it seems you are using advanced indexing just as a way to keep the dimension. If that is true, using a slice containing a single element as I have shown is cleaner (my opinion) and faster (tested with %timeit in IPython).
Now, back to your question. It looks like you want to extract all values whose index of the second dimension is equal to 1, similar to the red part in the figure below.
If that is the case, then just use either image[:,1, :] (or just image[:,1]) if you to get the values as a matrix, or image[:,1:2, :] if you want a 3D array.
It is also useful to understand what your failed attempts were actually doing.
image[:,[1]][3]: This is actually two indexing operations in the same line.
First, image[:,[1]] would return a 100x1x3 array, and then the second indexing with [3] would take the fourth line. Since this second indexing is a regular one (not a fancy and not a slice), then the indexed dimension disappears and you get a 1x3 array in the end
image[:,[1][3]]: This one I'm not really sure what it is doing
image[:,[1],[3]]: This means "take all values from the first dimension, but only the ones from the second index of the first dimension and the fourth index of the third dimension. Since the third dimension only has "size" 3, then trying to get the fourth index results in the out of bound error.

Removing every other element in NumPy

I can't for the life of me figure this out.
I'm trying to remove every other element in the second axis of an array. I did this in MATLAB with arr(:,:,2:2:end) = [];, but when I tried to do the same in Python and compare the two outputs, I get a different matrix.
I've tried arr = np.delete(arr,np.arange(0,arr.shape[2],2),2) and arr = arr[:,:,1::2], but neither seem to come up with something I get with MATLAB.
Example:
MATLAB
disp(['before: ',str(arr[21,32,11])])
arr(:,:,2:2:end) = [];
disp(['after: ',str(arr[21,32,11])])
output:
before: 99089
after: 65699
Python
print 'before: ' + str(arr[20,31,10])
arr = arr[:,:,1::2] # same output as np.delete(arr,np.arange(0,arr.shape[2],2),2)
print 'after: ' + str(arr[20,31,10])
output:
before: 99089
after: 62360
I hope I'm not overlooking something fundamental.
You are trying to delete every other element starting from the second element onwards in the last axis. In other words, you are trying to keep every other element starting from the first element onwards in that axis.
Thus, working the other way around of selecting elements instead of deleting elements, the MATLAB code arr(:,:,2:2:end) = [] would be equivalent to (neglecting the performance numbers) :
arr = arr(:,:,1:2:end)
In Python/NumPy, this would be:
arr = arr[:,:,0::2]
Or simply:
arr = arr[:,:,::2]

Categories

Resources