Search a tensor for data/values - python

Given:
tensor([[6, 6],
[4, 8],
[7, 5],
[7, 4],
[6, 4]])
How do I find the index of rows with values [7,5]?
In general, how do I search for indices of any values: full and partial row or column?

Try with this:
>>> (a[:, None] == torch.tensor([7, 5])).all(-1).any(-1).nonzero().flatten().item()
2
>>>

Related

Slicing a matrix by an index matrix in TensorFlow

I have an n-by-m matrix X and an n-by-r index matrix I. I am wondering what are the relevant TensorFlow operators that allow me to get an n-by-r matrix R such that R[i,j] = X[i,I[i,j]]. As an example, let's say
X = tf.constant([[1,2,3],
[4,5,6],
[7,8,9]])
I = tf.constant([[1,2],
[1,0],
[0,2]])
The desired result would be a tensor
R = [[2, 3],
[5, 4],
[7, 9]]
I tried to use each column of the matrix I as the index and do tf.diag_part(tf.gather(X', index)), which seems to give me one column of R if I has the same number of row as X. For example,
idx = tf.transpose(I)[0] #[1,1,0]
res = tf.diag_part(tf.gather(tf.transpose(X), idx))
# res will be [2,5,7], i,e, first colum of R
Another attempt:
res = tf.transpose(tf.gather(tf.transpose(X), I),[0,2,1])
print(res.eval())
array([[[2, 3],
[5, 6],
[8, 9]],
[[2, 1],
[5, 4],
[8, 7]],
[[3, 1],
[6, 4],
[7, 9]]], dtype=int32)
From here i just need to be able to select the "diagonal entries" res[0,0], res[1,1] and res[2,2] to get R. I get stuck here though...
Use tf.gather with batch_dims argument:
res = tf.gather(X, I, batch_dims=1)

Can't index multiple elements in list of lists in Python (using the : operator)

I found it strange that indexing using range(:) operator for list of lists is not supported.
Sometimes this result in strange values :
a = [[1, 2], [3, 4], [5, 6], [7, 8]]
>>> a
[[1, 2], [3, 4], [5, 6], [7, 8]]
>>> a[0][1]
2
>>> a[1][1]
4
>>> a[2][1]
6
However,
>>> a[0:3][1]
[3, 4]
I was expecting [2,4,6]. What am I missing here ?
I tried this on Numpy arrays as well.enter code here
>>> a
[[1, 2], [3, 4], [5, 6], [7, 8]]
>>> a[0][1]
2
>>> a[1][1]
4
>>> a[2][1]
6
>>> a[0:3][1]
[3, 4]
I know I can use list comprehension, but my question is whether ":" is supported for list of lists?
numpy arrays do support slicing, but you're not considering the shape of the array. In numpy, this array has shape:
import numpy as np
a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print(a.shape)
>>>(4, 2)
meaning it's 4x2. If you slice [0:3] you're returning the first three elements of the 1st dimension. i.e.:
print(a[0:3])
>>>[[1 2]
[3 4]
[5 6]]
this output has shape:
print(a[0:3].shape)
>>>(3, 2)
if you do:
print(a[0:3][1])
>>>[3 4]
You are again calling the first element of the first dimension of the array that has shape (3, 2).
Instead you want to call:
print(a[0:3][:,1])
>>>[2 4 6]
Which gives you all of the row elements (i.e. all three elements of the first dimension) at column index 1 (where 0 and 1 represent the indexes for the two dimensions of the second dimension).
even cleaner (recommended):
print(a[0:3, 1])
>>>[2 4 6]
Using : is totally supported. Explained below...
So we start with:
a = [[1, 2], [3, 4], [5, 6], [7, 8]]
You asked about:
a[0:3][1]
We want the items from list a, from positions zero to three [0:3]. Those items returned are
[1, 2] --- position 0
[3, 4] --- position 1
[5, 6] --- position 2
[7, 8] --- position 3
Then we request from that list the item in position 1, which returns:
[3, 4]
If you want to access items inside that smaller list you need to add another index, like this:
a[0:3][1][1]
would return:
4
Diagram of basic string splitting:
Your first bracket (represented in blue) is saying "give me elements in list a between positions 0 and 3, which in this case, is ALL of them.
Your second bracket (represented in red) is saying "of the results of my first bracket, give me the element that is in position 1", which is the entire sub-list [3,4]
In this specific case
a[0:3][1]
could have simply been written as
a[1]
let us assume a list of list
list=[[1,2],[3,4],[5,6],[7,8]]
then,
list[0:3]
will return a list with elements(which are also list) from index 0 to 2
[[1, 2], [3, 4], [5, 6]]
so according list[0:3][1] will return the second element([3,4]) whose index is "1" .
a[0:3][1] will not return[2,4,6] , it returns the list of list with 3 element and chooses the second element.
When you call a[0:3] the result of that is a list with the first three elements of a. You then call a[0:3][1] which returns the 2nd element of that list which is the list [3,4].
Ordinary Python lists do not support this kind of slicing.
You can get [2, 4, 6] with Numpy:
>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
>>> a[0:3, 1]
array([2, 4, 6])
a = [[1, 2], [3, 4], [5, 6], [7, 8]]
a[0:3]
the output of this is a list:
>>> [[1, 2], [3, 4], [5, 6]]
Therefore:
a[0:3][1]
Accesses the element at index 1, which is [3, 4]
To get the desired output from your list, use list comprehension:
[x[1] for x in a[0:3]]
>>> [2, 4, 6]

Match array values with array values in multi-dimensional array

I have 2 arrays:
[1, 2, 3, 4, 5]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Is there a way I can find the number of sub-array in the second array which contains the values of the first array using Python?
For the above, it would be 2
You can try this:
s = [1, 2, 3, 4, 5]
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
final_val = len([i for i in a if any(b in s for b in i)])
Output:
2
Yes, for each element in the first array, you must check if it is in the sub-arrays of the second.
However, this is quite inefficient, so you can proceed like this:
For each sub array in second, check it it contains any element of First, if it is the case, add one to the count, and check the next sub array.
first = [1, 2, 3, 4, 5]
second = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matches = 0
for sub in second:
for elt in sub:
if elt in first:
matches += 1
break
print(matches)

Combine values from 2 dicts into a np.array python

I have two dicts
a = {0:[1,2,3,4], 1:[5,6,7,8],...}
b = {0:[4,3,2,1], 1:[8,7,6,5],...}
I would like to create an np.array c for each key-value pair such as follows
c1 = array([[1,4],[2,3],[3,2],[4,1]])
c2 = array([[5,8],[6,7],[7,6],[8,5]])
How can I do this? Is it possible to store np.array in a python dict so that I can create a single dict c instead of multiple arrays
Yes, you can put np.array into a Python dictionary. Just use a dict comprehension and zip the lists from a and b together.
>>> a = {0:[1,2,3,4], 1:[5,6,7,8]}
>>> b = {0:[4,3,2,1], 1:[8,7,6,5]}
>>> c = {i: np.array(list(zip(a[i], b[i]))) for i in set(a) & set(b)}
>>> c
{0: array([[1, 4], [2, 3], [3, 2], [4, 1]]),
1: array([[5, 8], [6, 7], [7, 6], [8, 5]])}
You can also use column_stack with a list comprehension:
import numpy as np
[np.column_stack((a[k], b[k])) for k in b.keys()]
Out[30]:
[array([[1, 4],
[2, 3],
[3, 2],
[4, 1]]), array([[5, 8],
[6, 7],
[7, 6],
[8, 5]])]

Modify a particular row/column of a NumPy array

How do I modify particular a row or column of a NumPy array?
For example I have a NumPy array as follows:
P = array([[1, 2, 3],
[4, 5, 6]])
How do I change the elements of first row, [1, 2, 3], to [7, 8, 9] so that the P will become:
P = array([[7, 8, 9],
[4, 5, 6]])
Similarly, how do I change second column values, [2, 5], to [7, 8]?
P = array([[1, 7, 3],
[4, 8, 6]])
Rows and columns of NumPy arrays can be selected or modified using the square-bracket indexing notation in Python.
To select a row in a 2D array, use P[i]. For example, P[0] will return the first row of P.
To select a column, use P[:, i]. The : essentially means "select all rows". For example, P[:, 1] will select all rows from the second column of P.
If you want to change the values of a row or column of an array, you can assign it to a new list (or array) of values of the same length.
To change the values in the first row, write:
>>> P[0] = [7, 8, 9]
>>> P
array([[7, 8, 9],
[4, 5, 6]])
To change the values in the second column, write:
>>> P[:, 1] = [7, 8]
>>> P
array([[1, 7, 3],
[4, 8, 6]])
In a similar way if you want to select only two last columns for example but all rows you can use:
print P[:,1:3]
If you have lots of elements in a column:
import numpy as np
np_mat = np.array([[1, 2, 2],
[3, 4, 5],
[5, 6, 5]])
np_mat[:,2] = np_mat[:,2] * 3
print(np_mat)
It is making a multiplied by 3 change in third column:
[[ 1 2 6]
[ 3 4 15]
[ 5 6 15]]

Categories