how to read the shape of the numpy array after numpy stack - numpy

I am doing stack operation on two 2D array using numpy.
a = np.random.randint(1, 5, size=(4, 4))
b = np.random.randint(6, 10, size=(4, 4))
f = np.stack((a, b), axis=2)
I checked the shape of the f array.
f.shape
(4, 4, 2)
in the obtained shape (4, 4, 2), I would like to know what is first 4 represnts, second 4 represents and third element 2 reprents?

Related

how do I select rows from pandas df without returning False values?

I have a df and I need to select rows based on some conditions in multiple columns.
Here is what I have
import pandas as pd
dat = [('p','q', 5), ('k','j', 2), ('p','-', 5), ('-','p', 4), ('q','pkjq', 3), ('pkjq','q', 2)
df = pd.DataFrame(dat, columns = ['a', 'b', 'c'])
df_dat = df[(df[['a','b']].isin(['k','p','q','j']) & df['c'] > 3)] | df[(~df[['a','b']].isin(['k','p','q','j']) & df['c'] > 2 )]
Expected result = [('p','q', 5), ('p','-', 5), ('-','p', 4), ('q','pkjq', 3)]
Result I am getting is an all false dataframe
When you have the complicate condition I recommend, make the condition outside the slice
cond1 = df[['a','b']].isin(['k','p','q','j']).any(1) & df['c'].gt(3)
cond2 = (~df[['a','b']].isin(['k','p','q','j'])).any(1) & df['c'].gt(2)
out = df.loc[cond1 | cond2]
Out[305]:
a b c
0 p q 5
2 p - 5
3 - p 4
4 q pkjq 3

Matrix Vector Product across Multiple Dimensions

I have two arrays:
A = torch.rand((64, 128, 10, 10))
B = torch.rand((64, 128, 10))
I would like to compute the product, represented by C, where we do a matrix-vector multiplication across the first and second dimensions of A and B, so:
# C should have shape: (64, 128, 10)
for i in range(0, 64):
for j in range(0, 128):
C[i,j] = torch.matmul(A[i,j], B[i,j])
Does anyone know how to do this using torch.einsum? I tried the following, but I am getting an incorrect result.
C = torch.einsum('ijkl, ijk -> ijk', A, B)
Here's the options with numpy. (I don't have torch)
In [120]: A = np.random.random((64, 128, 10, 10))
...: B = np.random.random((64, 128, 10))
Your iterative reference case:
In [122]: C = np.zeros((64,128,10))
...: # C should have shape: (64, 128, 10)
...: for i in range(0, 64):
...: for j in range(0, 128):
...: C[i,j] = np.matmul(A[i,j], B[i,j])
...:
matmul with full broadcasting:
In [123]: D = np.matmul(A, B[:,:,:,None])
In [125]: C.shape
Out[125]: (64, 128, 10)
In [126]: D.shape # D has an extra size 1 dimension
Out[126]: (64, 128, 10, 1)
In [127]: np.allclose(C,D[...,0]) # or use squeeze
Out[127]: True
The einsum equivalent:
In [128]: E = np.einsum('ijkl,ijl->ijk', A, B)
In [129]: np.allclose(C,E)
Out[129]: True

Numpy Indexing of multidimensional array

I have an array x whose shape is (308, 308, 308). I have an array of integer indices v of shape (10, 308, 308, 3). I would like to index x so as to create a matrix y of shape (10, 308, 308) whose (i, j, k)-entry is x[tuple(v[i, j, k])]. Is there a fast way to accomplish this?

Multiply each channel by different matrix?

Is there a way, in tensorflow, to multiply each channel by a different matrix?
Imagine you have a 2D array A of dimensions (N, D1).
You can multiply it by an array B of size (D1, D2) to get output size (N, D2).
Now imagine you have a 3D array of dimensions (N, D1, 3).
Suppose you had B1, B2, B3 all of size (D1, D2). Combining the outputs A * B1, A * B2, A * B3, you could form an array of size (N, D2, 3).
But is there a way to get an output size of (N, D2, 3) by just doing multiplication once?
I looked into transpose and matmul but it doesn't seem to work for this purpose.
Thank you!
tf.einsum() could be applied here.
To make the code below easier to understand, I renamed D1 = O and D2 = P.
import tensorflow as tf
A = tf.random_normal([N, O, 3])
B = tf.random_normal([O, P, 3]) # B = tf.stack([B1, B2, B3], axis=2)
res = tf.einsum("noi,opi->npi", A, B)
You could use tf.matmul here. Its just that you will have to transpose the dimensions.
Consider, N = 2, D1 = 4, D2 = 5. First create two matrices having shapes N x D1 x 3 and D1 x D2 x 3.
a = tf.constant(np.arange(1, 25, dtype=np.int32), shape=[2,4,3])
b = tf.constant(np.arange(1, 61, dtype=np.int32), shape=[4,5,3])
Transpose the matrices so that the first dimension is the same.
a = tf.transpose(a, (2, 0, 1)) # a.shape = (3, 2, 4)
b = tf.transpose(b, (2, 0, 1)) # b.shape = (3, 4, 5)
Perform the multiplication as usual.
r = tf.matmul(a,b) # r.shape = (3, 2, 5)
r = tf.transpose(r, (1, 2, 0)) # r.shape = (2, 5, 3)
Hope this helps.

Pick random tensors from another one in Tensorflow

I have a Tensor X whith shape [B, L, E] (let's say, B batches of L vectors of length E). From this Tensor X, I want to randomly pick N vectors in each batch, and so create Y with shape [B, N, E].
I tried to combine tf.random_uniform and tf.gather but I really struggle with the dimension and can't get Y.
You can use something like this:
import tensorflow as tf
import numpy as np
B = 3
L = 5
E = 2
N = 3
input = np.array(range(B * L * E)).reshape([B, L, E])
print(input)
print("#################################")
X = tf.constant(input)
batch_range = tf.tile(tf.reshape(tf.range(B, dtype=tf.int32), shape=[B, 1, 1]), [1, N, 1])
random = tf.random_uniform([B, N, 1], minval = 0, maxval = L - 1, dtype = tf.int32)
indices = tf.concat([batch_range, random], axis = 2)
output = tf.gather_nd(X, indices)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(indices))
print("#################################")
print(sess.run(output))