get value from tensor by using index array python - python

I have an array A :
A = [[1, 2 ,3 ,4],
[5, 6 ,7 ,8],
[9, 10 ,11 ,12],]
and I want to get the 2nd row in the 3rd element (i.e. '7') :
I can do it by:
A[1,2]
For the general dimension number I want to have something generic.
Given index list B=[1,2]
I want to have something like MATLAB indexing:
A[B] or A[*B]
The first gives 2 rows and the second results in an error.
How can I do this?
edit: type(A)=type(B)=np.array

You don't need to unpack collection with "*" because numpy supports tuple indexing. You problem is that there is difference between indexing by list and by tuple. So,
import numpy as np
A = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
print("indexing by list:\n", A[[0, 1]], '\n')
# Output:
# indexing by list:
# [[1 2 3 4]
# [5 6 7 8]]
print("indexing by tuple:\n", A[(0, 1)])
# Output:
# indexing by tuple:
# 2
Hope, it helps. For the further reading about numpy indexing.

As an alternative, suppose you are interested in "array indexing", i.e., getting an array of values back of length L, where each value in the array is from a location in A. You would like to indicate these locations via an index of some kind.
Suppose A is N-dimensional. Array indexing solves this problem by letting you pass a tuple of N lists of length L. The ith list gives the indices corresponding to the ith dimension in A. In the simplest case, the index lists can be length-one (L=1):
>>> A[[1], [2]]
array([7])
But the index lists could be longer (L=5):
>>> A[[1,1,1,1,0], [2,2,2,2,0]]
array([7, 7, 7, 7, 1])
I emphasize that this is a tuple of lists; you can also go:
>>> first_axis, second_axis = [1,1,1,1,0], [2,2,2,2,0]
>>> A[(first_axis,second_axis)]
array([7, 7, 7, 7, 1])
You can also pass a non-tuple sequence (a list of lists rather than a tuple of lists) A[[first_axis,second_axis]] but in NumPy version 1.21.2, a FutureWarning is given noting that this is deprecated.
Another example here: https://stackoverflow.com/a/23435869/4901005

Related

How to copy common elements in two arrays into a new array without using numpy

Can we get common elements in two arrays with loops and if condition?
#copy the members of 1st array that are present 2nd array to 3rd array
import array as ar
import numpy as np
a1=ar.array('i',range(10))
a2=ar.array('i',[2,3,5,8,9,11,12])
​
​
a3=np.intersect1d(a1, a2)
​
print(a3)
type(a3)
#output
[2 3 5 8 9]
numpy.ndarray
Python list comprehension is a powerful thing:
a = [1, 2, 3, 4]
b = [3, 5, 4, 6]
c = [ x for x in a if x in b]
print(c)
# Output: [3, 4]
There are two ways to do it.
Lets take two arrays arr1 and arr2 and an empty array arr3.
arr1 = [i for i in range(1, 20)]
arr2 = [i for i in range(15, 25)]
arr3 = []
The conventional way would be to loop through the elements followed by an if statement that would check if the element is on the second array and append the element to the third array if the condition is satisfied.
arr3 = [i for i in arr1 if i in arr2]
Or you could convert the arrays into set and use intersection and convert them back.
arr3 = list(set(arr1).intersection(set(arr2)))
With the help of set operators, I was able to get common elements in 2 arrays and returned to 3rd array.
#copy the members of 1st array that are present 2nd array to 3rd array
import array as ar
a1=ar.array('i',range(10))
a2=ar.array('i',[2,3,5,8,9,12,13,15])
a3=ar.array(a1.typecode,(set(a1)&set(a2)))
print(a3)
type(a3)
#output
array('i', [2, 3, 5, 8, 9])
array.array
``

Mean of each element of matrices in a list

Hello I'm new in python I couldn't solve my problem. Suppose I have a list (a), this list has many matricies which is the same shape. I want to get one matrix that result of mean of each elements.
here is the list and its elements:
a[0]=[1 2 3]
a[1]=[3 4 5]
a[2]=[6 7 8]
Here is the desired matrix:
mean=[10/3 13/3 16/3]
Mean of each element of a list of matrices
Actually, this answer is good for me but it's for the R, not python. Sorry if I made a mistake while asking a question.
Using Python list comprehension
a = [[1, 2, 3],
[3, 4, 5],
[6, 7, 8]]
mean = [sum(row)/len(row) for row in zip(*a)] # use zip(*a) to transpose matrix
# since sum along columns
# by summing rows of transposed a
# [3.3333333333333335, 4.333333333333333, 5.333333333333333]
Here is a pure python solution that would work with any matrice dimension:
matrice = [
[1, 2, 3],
[3, 4, 5],
[6, 7, 8]
]
def mean_mat(mat):
dim_axis_0 = mat.__len__()
mean = [0 for i in range(dim_axis_0)]
for vector in mat:
for i, value in enumerate(vector):
mean[i] += (value / dim_axis_0)
return mean
print(mean_mat(matrice))
>>> [3.333333333333333, 4.333333333333334, 5.333333333333334]
However, as user1740577 pointed out, you should checkout the Numpy library.
try this:
import numpy as np
a= [[1,2,3],[3,4,5],[6,7,8]]
np.mean(a, axis=0)
# array([3.33333333, 4.33333333, 5.33333333])

Numpy: Indices of multiple values

I would like to set some values of a 2D array to a specific number by indexing them efficiently.
Say I have a 2D numpy array,
A = array([[1, 6, 6],
[9, 7, 7],
[10, 2, 2]])
and I would like to get the indices in the array that belong to a set of numbers, say indList=[10, 1] so that I can set them to zero. However, indList can be a huge list.
Is there a faster way for doing this without a for loop?
As a for loop it would be,
indList = [10, 1]
for i in indList:
A[A==i] = 0
But this can get inefficient when indList is large.
With numpy, you can vectorize this by first finding the indices of elements that are in indList and then setting them to be zero.
A = np.array([[1, 6, 6],
[9, 7, 7],
[10 ,2 ,2]])
A[np.where(np.isin(A, [10,1]))] = 0
This gives
A = [[0 6 6]
[9 7 7]
[0 2 2]]
From #Miket25's answer, there is actually no need to add the np.where layer. np.isin(A, [10, 1]) returns a boolean array which is perfectly acceptable as an index. So simply do
A[np.isin(A, [10, 1])] = 0

masking array with logical values along an arbitrary axis

Suppose I have a multidimensional array and a vector of logical values. I want to select items along an arbitrary (n-th) dimension. In the following example I am going to select the first and third values along the second dimension:
>>> A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> mask = np.array([True, False, True, False])
>>> dim_to_mask = 1 # i.e. 2nd dimension because it's 0-indexed
>>> B = ... # here do mask the dim_to_mask-th dimension - HOW???
>>> B
[[1, 3],
[5, 7],
[9, 11]]
Note: assume that the length of the logical vector corresponds to the length of the given axis.
I know it would be easy if the array is just one-dimensional using [] operator, but this is multidimensional problem.
Actually I want something like function take(indices, axis) which selects given indices along an arbitrary axis. The only difference is that I do have logical values instead of numeric indices.
I am also aiming at the fastest solution so converting vector of logical values to indices and using take is probably not the best solution.
I guess it must be something obvious which I am missing. :)
You could use np.compress:
>>> A.compress(mask, axis=1)
array([[ 1, 3],
[ 5, 7],
[ 9, 11]])
This function returns slices of an array along a particular axis. It accepts a boolean array with which to make the selections.

Index a numpy array using a list in a pythonic way

Imagine that I have a python array like
array = [[2,3,4],[5,6,7],[8,9,10]]
And a list
list = [0,2,1]
I basically want a one liner to extract the indexed elements from the array given by the list
For example, with the given array and list:
result = [2,7,9]
My kneejerk option was
result = array[:, list]
But that did not work
I know that a for cycle should do it, I just want to know if there is some indexing that might do the trick
Something like this?
In [24]: a
Out[24]:
array([[ 2, 3, 4],
[ 5, 6, 7],
[ 8, 9, 10]])
In [25]: lis
Out[25]: [0, 2, 1]
In [26]: a[np.arange(len(a)), lis]
Out[26]: array([2, 7, 9])
Use enumerate to create row indices and unzip (zip(*...)) this collection to get the row indices (the range [0, len(list))) and the column indices (lis) :
a[zip(*enumerate(lis))]

Categories