How to extend an numpy array with two index array [duplicate] - python

This question already has answers here:
Indexing one array by another in numpy
(4 answers)
Closed 3 years ago.
I have an numpy matrix, for example:
a = np.array([[1, 2], [3, 4]])
Then, I want to use another numpy matrix with indexes to extend the matrix, for example:
idxes = np.array(([0, 1, 0], [1, 0, 1]]) # the indexes matrix
The operation is like:
result = a[:, idxes] # this is an wrong expression
The result I expected is:
>>result
array([[1, 2, 1],
[4, 3, 4]])
I want to know how to do that.

You'll need to specify the a range for the first (0th) axis.
a[np.arange(len(a))[:,None], idxes]
This intuitively follows the indexing operation, the first row of idxes will index into the first row of a, the second row of idxes will index the second row of a, and so on.
Additionally, the dimensions of arange array need to be expanded from 1D to 2D because idxes is also a 2D array.

A fun way diagonal + take, diagonal here make sure you always slice the row index equal to the columns index items , which will return the just like row-wise out put
np.diagonal(np.take(a, idxes,1)).T
array([[1, 2, 1],
[4, 3, 4]])
Or
np.diagonal(a[:,idxes]).T
array([[1, 2, 1],
[4, 3, 4]])

Related

numpy: split 2d numpy array and then create 2d diagonal block array [duplicate]

This question already has answers here:
How can I transform blocks into a blockdiagonal matrix (NumPy)
(3 answers)
Closed 1 year ago.
Suppose, I got a 2D (n \times 2*n) numpy array like below,
dat = np.array([[1,2,3,4],[5,6,7,8]])
I want to split it into two 2d array equally, and then create a 2d diagonal block array, like below,
a = dat[:,0:2]
b = dat[:,2:]
result = np.block([
[a, np.zeros((2, 2))],
[np.zeros((2, 2)), b ]
])
Is there any better way in numpy that I dont need to specify this part "np.zero((n,n))"
Use scipy.linalg.block_diag
>>> import scipy.linalg
>>> scipy.linalg.block_diag(a, b)
array([[1, 2, 0, 0],
[5, 6, 0, 0],
[0, 0, 3, 4],
[0, 0, 7, 8]])
Taken from this post

Searching a Numpy Array for the index of a subarray based on a subarray of the subarray

I want to get the index of a 2d array which contains a specific array. In this case I want to know where in the array array the array [[4, 5], 6] is but only based on the inner most array [4, 5] so that I get its position even if instead of the six it would be an eight.
This is my code so far:
import numpy as np
array = np.array([[[1, 2], 3], [[4, 5], 6], [[7, 8], 9]])
print(np.where(array == [4, 5]))
but as an output I get:
(array([], dtype=int32), array([], dtype=int32))
and the output I want is the following:
(array([1], dtype=int32), array([0], dtype=int32))
The issue is that you are working with a dtype object where your first numpy column contains list objects.
You can create a vectorized function to check each object individually.
f = np.vectorize(lambda x: x==[4,5])
idx = np.where(f(array))
idx
(array([1]), array([0]))
You can also use a list comprehension after flattening out the array and then checking each object against [4,5]. Then you could use np.where or just plain simple boolean check to get the index in that flat list, which you could unravel_index to get the position in the 2D array. (I am using np.where because you want to use it)
check = [i==[4,5] for i in array.ravel()]
np.unravel_index(*np.where(check), array.shape)
(array([1]), array([0]))

add numpy subarray to numpy array based on condition

I have a 2d numpy array and a 2d numpy subarray that I want to add to the original array based on a condition.
I know that you can add the 2d subarray to the array like this:
original_array[start_x:end_x, start_y:end_y] = sub_array
but I dont know how to efficiently add only values of the sub_array that are bigger than 0?
Example:
orginal_array = np.array([2,2],[2,2],[2,2],[2,2])
sub_array = np.array([0,0],[1,1],[0,1],[0,0])
expected_result = np.array([2,2], [1,1], [2,1], [2,2])
You can index based on the condition >,< 0 and add the arrays.
orginal_array * (sub_array <= 0) + sub_array * (sub_array > 0)
array([[2, 2],
[1, 1],
[2, 1],
[2, 2]])
Another approach is to use the np.where function as:
np.where(sub_array > 0, sub_array, original_array)
Output:
array([[2, 2],
[1, 1],
[2, 1],
[2, 2]])
Try,
sub_array2 = np.select([sub_array>0],[sub_array])
original_array[start_x:end_x, start_y:end_y] = sub_array2

How to apply slice operator to get n-th column of an array in python? [duplicate]

This question already has an answer here:
Python: slicing a multi-dimensional array
(1 answer)
Closed 3 years ago.
I have 2-D matrix of size n, I want to get the entire n-1th column values into another list. For example,
a = [[1, 2], [3, 4], [5, 6]]
a[:][0] // return [1,2]
how to get 1,3,5 for above a 2-D array into a list using slice operator
To my knowledge, the array slice operator is not suited for what you're looking for.
I would recommend python's list comprehensions.
a = [[1, 2], [3, 4], [5, 6]]
result = [x[0] for x in a]
print(result)
You can do this using the numpy library:
import numpy
a = np.array([[1, 2], [3, 4], [5, 6]])
result = a[:, 0] # Returns a 1-D numpy array [1, 3, 5]
More advanced indexing and slicing options can be found here.

about python matrix logical indexing

I'm newbie in python and I don't understand the following code;
I expected that test1 and test2 give me same results (8, the sum of second row), instead
a=np.matrix([[1,2,3],[1,3, 4]])
b=np.matrix([[0,1]])
print(np.where(b==1))
test1=a[np.nonzero(b==1),:]
print(test1.sum())
ind,_=np.nonzero(b==1); #found in a code that I'm trying to undestand (why the _ ?)
test2=a[ind,:]
print(test2.sum())
gives me
(array([0]), array([1]))
14
6
in the first case I have the sum of the full matrix, in the second case I have the sum of the first row (instead of the 2nd)
I don't understand why this behavior
In [869]: a
Out[869]:
matrix([[1, 2, 3],
[1, 3, 4]])
In [870]: b
Out[870]: matrix([[0, 1]])
In this use where is the same as nonzero:
In [871]: np.where(b==1)
Out[871]: (array([0], dtype=int32), array([1], dtype=int32))
In [872]: np.nonzero(b==1)
Out[872]: (array([0], dtype=int32), array([1], dtype=int32))
It gives a tuple, one indexing array for each dimension (2 for an np.matrix). The ind,_= just unpacks those arrays, and throws away the 2nd. _ is reused in an interactive session such as the one I'm using.
In [873]: ind,_ =np.nonzero(b==1)
In [874]: ind
Out[874]: array([0], dtype=int32)
Selecting with where returns (0,1) value from a. But is that what you want?
In [875]: a[np.where(b==1)]
Out[875]: matrix([[2]])
Adding the : does index the whole array, but with an added dimension; again probably not what we want
In [876]: a[np.where(b==1),:]
Out[876]:
matrix([[[1, 2, 3]],
[[1, 3, 4]]])
ind is a single indexing array, and so selects the 0's row from a.
In [877]: a[ind,:]
Out[877]: matrix([[1, 2, 3]])
In [878]:
But is the b==1 supposed to find the 2nd element of b, and then select the 2nd row of a? To do that we have to use the 2nd indexing array from where:
In [878]: a[np.where(b==1)[1],:]
Out[878]: matrix([[1, 3, 4]])
Or the 2nd column from a corresponding to the 2nd column of b
In [881]: a[:,np.where(b==1)[1]]
Out[881]:
matrix([[2],
[3]])
Because a and b are np.matrix, the indexing result is always 2d.
For c array, the where produces a single element tuple
In [882]: c=np.array([0,1])
In [883]: np.where(c==1)
Out[883]: (array([1], dtype=int32),)
In [884]: a[_,:] # here _ is the last result, Out[883]
Out[884]: matrix([[1, 3, 4]])
We generally advise using np.array to construct new arrays, even 2d. np.matrix is a convenience for wayward MATLAB users, and often confuses new numpy users.

Categories

Resources