Related
I have the following two PyTorch tensors A and B.
A = torch.tensor(np.array([40, 42, 38]), dtype = torch.float64)
tensor([40., 42., 38.], dtype=torch.float64)
B = torch.tensor(np.array([[[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]], [[4,5,6,7,8],[4,5,6,7,8],[4,5,6,7,8],[4,5,6,7,8],[4,5,6,7,8]], [[7,8,9,10,11],[7,8,9,10,11],[7,8,9,10,11],[7,8,9,10,11],[7,8,9,10,11]]]), dtype = torch.float64)
tensor([[[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.]],
[[ 4., 5., 6., 7., 8.],
[ 4., 5., 6., 7., 8.],
[ 4., 5., 6., 7., 8.],
[ 4., 5., 6., 7., 8.],
[ 4., 5., 6., 7., 8.]],
[[ 7., 8., 9., 10., 11.],
[ 7., 8., 9., 10., 11.],
[ 7., 8., 9., 10., 11.],
[ 7., 8., 9., 10., 11.],
[ 7., 8., 9., 10., 11.]]], dtype=torch.float64)
Tensor A is of shape:
torch.Size([3])
Tensor B is of shape:
torch.Size([3, 5, 5])
How do I multiply tensor A with tensor B (using broadcasting) in such a way for eg. the first value in tensor A (ie. 40.) is multiplied with all the values in the first 'nested' tensor in tensor B, ie.
tensor([[[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.],
[ 1., 2., 3., 4., 5.]],
and so on for the other 2 values in tensor A and the other two nested tensors in tensor B, respectively.
I could do this multiplication (via broadcasting) with numpy arrays if A and B are arrays of both shape (3,) - ie. A*B - but I can't seem to figure out a counterpart of this with PyTorch tensors. Any help would really be appreciated.
When applying broadcasting in pytorch (as well as in numpy) you need to start at the last dimension (check out https://pytorch.org/docs/stable/notes/broadcasting.html). If they do not match you need to reshape your tensor. In your case they can't directly be broadcasted:
[3] # the two values in the last dimensions are not one and do not match
[3, 5, 5]
Instead you can redefine A = A[:, None, None] before muliplying such that you get shapes
[3, 1, 1]
[3, 5, 5]
which satisfies the conditions for broadcasting.
I'm trying to do multiplication of all the combination of elements in a certain dimension.
For example,
using for loops it would be
for a,i in enumerate(A):
for b,j in enumerate(B):
c[i][j] = a[1]*b[0]
not using for loop would be
A[:,None,1]*B[:,0]
this worked fine for 2-dimensions(A.shape=(4,2),B.shape=(4,2)).
However, When I am expanding above procedures to 3-dimensions(A.shape=(2,4,2),B.shape=(2,4,2)).
I tried with
A[:,:,1]*B[:,:,None,0]
but gives me an error.
How can I do this without using for loops???
For 2-dimensional tensors this is what I get
a = torch.FloatTensor([[0,1],[0,2],[0,3],[0,4]])
b = torch.FloatTensor([[1,0],[2,0],[3,0],[4,0]])
c = a[:,None,0] * b[:,1]
print(c)
tensor([[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]])
but in the case of
A = torch.cat([a.unsqueeze(0),a.unsqueeze(0)],dim=0)
B = torch.cat([b.unsqueeze(0),b.unsqueeze(0)],dim=0)
C = A[:,:,None,0] * B[:,:,1] << RuntimeError
RuntimeError: The size of tensor a (4) must match the size of tensor b (2) at non-singleton dimension 1
what I want is
tensor([[[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]],
[[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]]])
I cannot think of a way to do this without using for loop in dimension 0.
I have tensorA of size 10x4x9x2, the other tensorB is of size 10x5x2 that contains values from tensorA. Now, how can i find the index of each element in tensorB in tensorA.
Example:
First 2 elements of TensorA:
[[[[ 4., 1.],
[ 1., 2.],
[ 2., 5.],
[ 5., 3.],
[ 3., 11.],
[11., 10.],
[10., -1.],
[-1., -1.],
[-1., -1.]],
[[12., 13.],
[13., 9.],
[ 9., 7.],
[ 7., 5.],
[ 5., 3.],
[ 3., 4.],
[ 4., 1.],
[ 1., 0.],
[ 0., -1.]],
...... so on
Fist 2 elements of TensorB:
[[[ 2., 5.],
[ 5., 7.],
[ 7., 9.],
[ 9., 10.],
[10., 12.]],
[[ 0., 1.],
[ 1., 2.],
[ 2., 5.],
[ 5., -1.],
[-1., -1.]],
Now in tensorB the first element is [2,5] included in the first 5x2 matrix (dimension 0).
so the element should be matched against dimension 0 in tensorA. And the output should be index
0,0,2 since it is the 3rd element.
You can compare the rows that are equal, sum along the last axis, and check that sum against the size of the searched tensor. Then the nonzero function will get you the indices you're looking for.
Since for the example tensors you have given, TensorB[0, 0] is [2., 5.], that looks like:
((TensorA == TensorB[0, 0]).sum(dim=3) == 2).nonzero()
This will return a tensor of [[0, 0, 2]] if that is the only matching row. If you don't want to hard-code 2 (the size of the searched tensor), you can use:
((TensorA == TensorB[0, 0]).sum(dim=3) == TensorB[0, 0].size()[0]).nonzero()
I have two numpy array like this,
this is the first one, called "pred_test"
array([2., 2., 2., 2., 2., 1., 2., 2., 2., 3., 2., 2., 3., 2., 2., 2., 2.,
2., 3., 3.], dtype=float32)
and this is the second one, called "pred_train"
array([13., 11., 9., 5., 5., 3., 2., 1., 1., 1., 4., 5., 11.,
9., 9., 4., 4., 3., 2., 1., 1., 1., 2., 1., 11., 12.,
8., 3., 3., 4., 4., 2., 2., 1., 2., 2., 4., 3., 2.,
1., 1., 1., 1., 1., 2., 1., 1., 2., 3., 2., 3., 2.,
2., 2., 2., 2., 2., 1., 2., 2., 10., 2., 2., 2., 2.,
2., 2., 3., 3., 2., 2., 3., 4., 2., 3., 3.],
dtype=float32)
How can i combine the two array to look like pred_train + pred test, something like this..
[2., 2., 2., 2., 2., 1., 2., 2., 2., 3., 2., 2., 3., 2., 2., 2., 2., 2., 3., 3.,
13., 11., 9., 5., 5., 3., 2., 1., 1., 1., 4., 5., 11.,
9., 9., 4., 4., 3., 2., 1., 1., 1., 2., 1., 11., 12.,
8., 3., 3., 4., 4., 2., 2., 1., 2., 2., 4., 3., 2.,
1., 1., 1., 1., 1., 2., 1., 1., 2., 3., 2., 3., 2.,
2., 2., 2., 2., 2., 1., 2., 2., 10., 2., 2., 2., 2.,
2., 2., 3., 3., 2., 2., 3., 4., 2., 3., 3.]
Can someone help me? Thank you..
Use numpy.concatenate((pred_test, pred_train))
You can go with:
np.append(pred_test, pred_train)
I have a 2d numpy array my_array that starts out like this:
array([[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 6., 7., 8., 9.]])
But after some processing which is irrelevant now looks like this:
array([[1., 2., 0., 4., 5., 6., 0., 8., 9.],
[0., 2., 0., 0., 5., 6., 7., 8., 9.],
[0., 2., 0., 4., 5., 0., 7., 0., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 0., 7., 8., 9.],
[0., 2., 0., 4., 5., 6., 0., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 0.]])
As you can see, some of the items have been "zeroed out" quite randomly, but only the value of 3 was left with only 1 item that isn't zero. I'm looking for a function that takes this array and returns the index / row number that has the value 3 (or any other value that only appears once and only once in the array).
To explain this differently:
I first have to figure out if there is such an item that only appears once (in this example the answer is yes and that item is the number 3), and then I need to return its row number (in this case 4 since the only line with 3 in it is: my_array[4])
I have successfully done that with iterating over the array, item by item, and counting the number of times each number appears (and returning only the item whose count is 1) and then iterating over everything a second time to find the correct index / row number of where that item is located.
This seems very inefficient, especially if the array will be larger. Is there a better way in numpy to do this?
EDIT: if the number that appears only once is 0 that shouldn't count, i'm only looking for the "column" that was zeroed-out completely except 1 item in it
Try using the numpy.count_nonzero method
numpy.count_nonzero(arr, axis=0)
This will count the non-zero values columnwise
Here's a Demo
I will leave the rest to you. Good Luck
Edit I wasn't even using the mask, you can just use the first and last lines:
x = np.array([[1., 2., 0., 4., 5., 6., 0., 8., 9.],
[0., 2., 0., 0., 5., 6., 7., 8., 9.],
[0., 2., 0., 4., 5., 0., 7., 0., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 3., 4., 5., 0., 7., 8., 9.],
[0., 2., 0., 4., 5., 6., 0., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 9.],
[1., 2., 0., 4., 5., 6., 7., 8., 0.]])
res = (x == 3)
print(np.where(res * x)[0])
Output:
[4]
The full response to np.where() is:
(array([4], dtype=int64), array([2], dtype=int64))
So if you wanted both the column and the row number, you could use both of these.