Reverse Index through a numPy ndarray - python

I have a n x n dimensional numpy array of eigenvectors as columns, and want to return the last v of them as another array. However, they are currently in ascending order, and I wish to return them in descending order.
Currently, I'm attempting to index as follows
eigenvector_array[:,-1:-v]
But this doesn't seem to be working. Is there a more efficient way to do this?

Given a 2d array:
In [44]: x = np.arange(15).reshape(3,5);x
Out[44]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
the last 3 columns:
In [45]: x[:,-3:]
Out[45]:
array([[ 2, 3, 4],
[ 7, 8, 9],
[12, 13, 14]])
and reversing their order:
In [46]: x[:,-3:][:,::-1]
Out[46]:
array([[ 4, 3, 2],
[ 9, 8, 7],
[14, 13, 12]])
Or we could reverse the order, and take the first n. x[:,::-1][:,:3]
I tried combining the selection and order, but getting the end points is trickier. Separating the operations is easier.
x[:,:-4:-1]

Lets re-write this to make it a little less confusing.
eigenvector_array[:,-1:-v]
to:
eigenvector_array[:][-1:-v]
Now remember how slicing works in python:
[start:stop:step]
If you set step. to -1 it will return them in reverse, so:
eigenvector_array[:,-1:-v:-1] should be your answer.

Related

if i have ndarray as say n=np.arange(16).reshape(4,4), which is the second to last axis?

I was going through one of the documentation of NumPy module, I come across something like : If a is an N-D array and b is an M-D array (where M>=2), it is a sum product over the last axis of a and the second-to-last axis of b, I'm beginner to NumPy I thought there are only 2 axes 0 ( rows) and 1( columns) could someone please explain what it means? if I have ND array as say n=np.arange(16).reshape(4,4), which is the second to last axis?
when you first think of it as a simple data structure, you can think of 2-dimensional arrays as rows and columns. But here, instead of saying 0:represents row and 1:column, it is more correct to say 0:represents data and 1:represents dimensions.
In other words, you need to look at the dimension-based, not the axis-based.
np.arange(16).reshape(4,4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
Here, we get an array with n*m(4*4) ie 4 dimensions, and 16 data in it.
Below, we obtain a 2-dimensional array containing 16 data.
np.arange(16).reshape(8,2)
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15]])
As for the question you want to learn.
a=np.arange(16).reshape(4,4)
print(a[:,-2])
array([ 2, 6, 10, 14])
The above expression returns data in the second-to-last dimension.

Get element from array based on list of indices

z = np.arange(15).reshape(3,5)
indexx = [0,2]
indexy = [1,2,3,4]
zz = []
for i in indexx:
for j in indexy:
zz.append(z[i][j])
Output:
zz >> [1, 2, 3, 4, 11, 12, 13, 14]
This essentially flattens the array but only keeping the elements that have indicies present in the two indices list.
This works, but it is very slow for larger arrays/list of indicies. Is there a way to speed this up using numpy?
Thanks.
Edited to show desired output.
A list of integers can be used to access the entries of interest for numpy arrays.
z[indexx][:,indexy].flatten()
x = {"apple", "banana", "cherry"}
y = {"google", "microsoft", "apple"}
z = x.intersection(y)
print(z)
z => apples
If I understand you correctly, just use Python set. And then cast it to list.
Indexing in several dimensions at once requires broadcasting the indices against each other. np.ix_ is a handy tool for doing this:
In [127]: z
Out[127]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [128]: z[np.ix_(indexx, indexy)]
Out[128]:
array([[ 1, 2, 3, 4],
[11, 12, 13, 14]])
Converting that to 1d is a trivial ravel() task.
Look at the ix_ produces, here it's a (2,1) and (1,4) array. You can construct such arrays 'from-scratch':
In [129]: np.ix_(indexx, indexy)
Out[129]:
(array([[0],
[2]]),
array([[1, 2, 3, 4]]))

Slicing a different range at each index of a multidimensional numpy array [duplicate]

This question already has answers here:
Selecting Random Windows from Multidimensional Numpy Array Rows
(2 answers)
Closed 3 years ago.
I have an m x n numpy array arr, and for each column of arr, I have a given range of rows that I want to access.
I have an n x 1 array vec that describes when this range starts.
The range has some constant duration d.
How can I extract this d x n array of interest efficiently?
Can this be done by clever slicing?
My initial thought was to try something like:
arr = np.tile(np.arange(10),(4,1)).T
vec = np.array([3,4,5,4])
d = 3
vec_2 = vec+d
out = arr[vec:vec2,np.arange(n)]
But this gives the following error:
TypeError: only integer scalar arrays can be converted to a scalar index
The desired output would be the following array:
array([[3, 4, 5, 4],
[4, 5, 6, 5],
[5, 6, 7, 6],
[6, 7, 8, 7])
I could loop over d, but performance is important for this piece of code so I would prefer to vectorize it.
In [489]: arr=np.arange(24).reshape(6,4)
In [490]: vec=np.array([0,2,1,3])
Taking advantage of the recent expansion of linspace to generate several arrays:
In [493]: x = np.linspace(vec,vec+2,3).astype(int)
In [494]: x
Out[494]:
array([[0, 2, 1, 3],
[1, 3, 2, 4],
[2, 4, 3, 5]])
In [495]: arr[x, np.arange(4)]
Out[495]:
array([[ 0, 9, 6, 15],
[ 4, 13, 10, 19],
[ 8, 17, 14, 23]])
the column iteration approach:
In [498]: np.stack([arr[i:j,k] for k,(i,j) in enumerate(zip(vec,vec+3))],1)
Out[498]:
array([[ 0, 9, 6, 15],
[ 4, 13, 10, 19],
[ 8, 17, 14, 23]])

Remove rows from numpy matrix

I have a list of integers which represent positions in a matrix (centre). For example,
centre = [2, 50, 100, 89]
I also have two numpy matrices, X and Y. I need to delete all of the rows from the matrix if the number is in the centre. I can do this:
for each in centre:
x = numpy.delete(x, (each), axis=0)
However, the numbers will all be out as the index's will all be out. So, how can I do this?
Just do the delete in one call:
In [266]: B
Out[266]:
array([[ 2, 4, 6],
[ 8, 10, 12],
[14, 16, 18],
[20, 22, 24]])
In [267]: B1=np.delete(B,[1,3],axis=0)
In [268]: B1
Out[268]:
array([[ 2, 4, 6],
[14, 16, 18]])
You question is a little confusing. I'm assuming that you want to delete rows by index number, not by some sort of content (not like the list find).
However if you must iterate (as with a list) do it in reverse order - that way indexing doesn't get messed up. You may have to sort the indices first (np.delete doesn't require that).
In [269]: B1=B.copy()
In [270]: for i in [1,3][::-1]:
...: B1=np.delete(B1,i,axis=0)
A list example that has to be iterative:
In [276]: B1=list(range(10))
In [277]: for i in [1,3,5,7][::-1]:
...: del B1[i]
In [278]: B1
Out[278]: [0, 2, 4, 6, 8, 9]
=============
With a list input like this, np.delete does the equivalent of:
In [285]: mask=np.ones((4,),bool)
In [286]: mask[[1,3]]=False
In [287]: mask
Out[287]: array([ True, False, True, False], dtype=bool)
In [288]: B[mask,:]
Out[288]:
array([[ 2, 4, 6],
[14, 16, 18]])

Numpy: how to add / join slice objects?

For a 2*N x 2*N array x, I'd like to swap rows [0:N] with rows [N:2*N] in a particular way, namely, the question I have is, if there is a 'built-in' way of 'adding / joining' slice objects to achieve this? I.e. something like:
x[N:2*N + 0:N,:]
although, the preceding does something different.
Certainly I could do things like vstack((x[N:2*N,:],x[0:N,:])), which is not really what I'm looking for, or x[[i for i in range(N)]+[i for i in range(N,2*N)],:], which probably is slow.
I think you're looking for numpy.r_, which "translates slice objects to concatenation along the first axis". It allows you to perform more complex slices along the first axis - you can concatenate multiple slices with commas: np.r_[5:10, 100:200:10, 15, 20, 0:5].
For example:
>>> import numpy as np
>>> N = 2
>>> x = np.arange(16).reshape(4, 4)
>>> x[np.r_[N:2*N, 0:N]]
array([[ 8, 9, 10, 11],
[12, 13, 14, 15],
[ 0, 1, 2, 3],
[ 4, 5, 6, 7]])
And in this specific case, you could also just np.roll it:
>>> np.roll(x, N, axis=0)
array([[ 8, 9, 10, 11],
[12, 13, 14, 15],
[ 0, 1, 2, 3],
[ 4, 5, 6, 7]])

Categories

Resources