Indexing N dimensional matrix [duplicate] - python

This question already has answers here:
using an numpy array as indices of the 2nd dim of another array? [duplicate]
(2 answers)
Closed 2 years ago.
I have the following array:
import numpy as np
print(A)
array([[ 0, 1, 4, 5, 8, 7],
[ 5, 3, 4, 1, 8, 11],
[ 2, 7, 5, 3, 4, 1],
[ 2, 8, 8, 1, 10, 1],
[ 2, 14, 8, 6, 5, 3]])
And I need to the values A corresponding to these column indices:
b = np.array([5, 0, 3, 4, 4])
Expected output:
array([ 7, 5, 3, 10, 5])
Thanks in advance.

You can use advanced indexing. You need to define an indexing array across the first axis, so that both indexing arrays are broadcast together and each column index refers to a specific row. In this case you just want an np.arange to index on the rows:
A[np.arange(A.shape[0]), b]
# array([ 7, 5, 3, 10, 5])

Related

Numpy/Torch : Selecting elements using indices over a dimension [duplicate]

This question already has answers here:
NumPy selecting specific column index per row by using a list of indexes
(7 answers)
Closed 1 year ago.
Given an array like below:
np.arange(12).reshape(4,3)
Out[119]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
I want to select a single element from each of the rows using a list of indices [0, 2, 1, 2] to create a 4x1 array of [0, 5, 7, 11].
Is there any easy way to do this indexing. The closest I could see was the gather method in pytorch.
>>> import torch
>>> import numpy as np
>>> s = np.arange(12).reshape(4,3)
>>> s = torch.tensor(s)
>>> s
tensor([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>> idx = torch.tensor([0, 2, 1, 2])
>>> torch.gather(s,-1 ,idx.unsqueeze(-1))
tensor([[ 0],
[ 5],
[ 7],
[11]])
torch.gather(s,-1 ,idx.unsqueeze(-1))
arr[[0,1,2,3], [0,2,1,2]]
or if you prefer np.arange(4) for the 1st indexing array.
Please try to run the following code.
import numpy as np
x = [[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]]
index_array = [0, 2, 1, 2]
index = 0
result = []
for item in x:
result.append(item[index_array[index]])
index += 1
print (result)
Here is the result.
[0, 5, 7, 11]
>

Change the format of a numpy array in python

I have a (2x2) numpy array which contains an (1x3) list, like this below:
[[ 1, 2, 3], [ 4, 5, 6]
[ 7, 8, 9], [10,11,12]]
and I want to break it to single elements like this (2x6) array (or matrix, I can't tell the difference):
[ 1, 2, 3, 4, 5, 6]
[ 7, 8, 9, 10, 11, 12]
I can create the second array by coping every single element of the first array and put it to the second one. Yet I wonder if there is a more easy way provided by the numpy library.
you can simply use resize function to do this
import numpy as np
a=[[ 1, 2, 3], [ 4, 5, 6],
[ 7, 8, 9], [10,11,12]]
a = numpy.array(a)
a.resize(2,6)
print(a)
OUTPUT
array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12]])

Creating a block array from a given array [duplicate]

This question already has answers here:
Quick way to upsample numpy array by nearest neighbor tiling [duplicate]
(3 answers)
Closed 2 years ago.
I have a 2d array like this
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
and I want to create an array, where every entry of the one above fills a whole block of the new array. I.e. if I want 2x2 blocks, I want my new array to look like this
B = np.array([[1, 1, 2, 2, 3, 3],
[1, 1, 2, 2, 3, 3],
[..., ..., ...,],
[..., 8, 8, 9, 9],
[..., 8, 8, 9, 9]])
I managed to do this by iterating over the arrays and creating a corresponding block for every entry, but I'm wondering if there's a better way to do this.
A.repeat(2, axis=1).repeat(2, axis=0)
First repeat the elements along the first axis to get:
array([[1, 1, 2, 2, 3, 3],
[4, 4, 5, 5, 6, 6],
[7, 7, 8, 8, 9, 9]])
Then repeat the elements along the zeroth axis to get:
array([[1, 1, 2, 2, 3, 3],
[1, 1, 2, 2, 3, 3],
[4, 4, 5, 5, 6, 6],
[4, 4, 5, 5, 6, 6],
[7, 7, 8, 8, 9, 9],
[7, 7, 8, 8, 9, 9]])
(The order of repetition axes doesn't matter.)
You can change 2s to the desired block size.

How to duplicate rows in a feature matrix array [duplicate]

This question already has answers here:
Resizing and stretching a NumPy array
(3 answers)
Closed 2 years ago.
Suppose I have the following feature matrix X (ie. with 4 rows and 3 features):
X = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
(array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]]),
How do I duplicate say, the 1st and 2nd row twice, the 3rd row 3 times and no duplication in the 4th row, ie. I want to get this:
(array([[ 1, 2, 3],
[ 1, 2, 3]
[ 4, 5, 6],
[ 4, 5, 6]
[ 7, 8, 9],
[ 7, 8, 9]
[ 7, 8, 9]
[10, 11, 12]]),
Is there a way for me to multiply the features matrix X with an array of weights, say something like this:
np.array([2,2,3,1])
Thanks in advance.
You can do it through indexing:
repeats = np.array([2,2,3,1])
indices = np.repeat(range(len(X)), repeats)
X[indices]
Where indices is
array([0, 0, 1, 1, 2, 2, 2, 3])
np.repeat(X, [2, 2, 3, 1], axis=0)

Numpy indexing: first (varying) number of elements from each row in 2d array

(short version of my question: In numpy, is there an elegant way of emulating tf.sequence_mask from tensorflow?)
I have a 2d array a (each row represents a sequence of different length). Next, there is a 1d array b (representing sequence lengths). Is there an elegant way to get a (flattened) array that would contain only such elements of a that belong to the sequences as specified by their length b:
a = np.array([
[1, 2, 3, 2, 1], # I want just [:3] from this row
[4, 5, 5, 5, 1], # [:2] from this row
[6, 7, 8, 9, 0] # [:4] from this row
])
b = np.array([3,2,4]) # 3 elements from the 1st row, 2 from the 2nd, 4 from the 4th row
the desired result:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
By elegant way I mean something that avoids loops.
Use broadcasting to create a mask of the same shape as the 2D array and then simply mask and extract valid elements -
a[b[:,None] > np.arange(a.shape[1])]
Sample run -
In [360]: a
Out[360]:
array([[1, 2, 3, 2, 1],
[4, 5, 5, 5, 1],
[6, 7, 8, 9, 0]])
In [361]: b
Out[361]: array([3, 2, 4])
In [362]: a[b[:,None] > np.arange(a.shape[1])]
Out[362]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

Categories

Resources