3-D numpy matrix multiplication in numpy to get 1 D array - python

I've 2 3-D matrix of this form:
a = np.random.randint(0, 100, size=(3, 4, 3))
b = np.random.normal(0, 1, size=(3,3, 4))
I want to multiply these 2 matrices, in such a way that I get a matrix of this form:
a_b = np.random.normal(0,1,size = (3,1))
I can change the matrix shape of b in anyway to get a_b shape. E.g. I can make b 2X2 matrix or change the shape of the matrix in any other way.
Can someone please guide me?
Thanks!

Related

Numpy Matrix Subtraction Different Dimensions

I currently have a 5D numpy array of dimensions 40 x 3 x 3 x 5 x 1000 where the dimensions are labelled by a x b x c x d x e respectively.
I have another 2D numpy array of dimensions 3 x 1000 where the dimensions are labelled by b x e respectively.
I wish to subtract the 5D array from the 2D array.
One way I was thinking of was to expand the 2D into a 5D array (since the 2D array does not change for all combinations of the other 3 dimensions). I am not sure what array method/numpy function I can use to do this.
I tend to start getting lost with nD array manipulations. Thank you for assisting.
In [217]: a,b,c,d,e = 2,3,4,5,6
In [218]: A = np.ones((a,b,c,d,e),int); B = np.ones((b,e),int)
In [219]: A.shape
Out[219]: (2, 3, 4, 5, 6)
In [220]: B.shape
Out[220]: (3, 6)
In [221]: B[None,:,None,None,:].shape # could also use reshape()
Out[221]: (1, 3, 1, 1, 6)
In [222]: C = B[None,:,None,None,:]-A
In [223]: C.shape
Out[223]: (2, 3, 4, 5, 6)
The first None isn't essential; numpy will add it as needed, but as a human it might help to see it.
IIUC, suppose your arrays are a and b:
np.swapaxes(np.swapaxes(a, 1, 3) - b, 1, 3)

Numpy Matrix Multiplication with Vectors

i wanna do a simple matrix multiplication with 2 Vectors: so that A * B.T = 3x3Matrix.
But somehow numpy returns a scalar or vector.
i already tried:
np.dot(a, b.transpose())
np.matmul(a, b.transpose())
a * b.transpose()
But nothins works, it seems like a simple operation to me, but i just cannot solve it
The reason why you are getting a scalar because you are multiplying two 1D vectors in numpy, which produces the inner product of 2 vectors. You need to reshape your vector to the shape (3,1), which turns them into a 2D shape and then you get the expected result upon performing the vector multiplication. Check the snippet below
>>> import numpy as np
>>> A = np.array([1,2,3])
>>> B = np.array([4,5,6])
>>> A.shape
(3,)
>>> B.shape
(3,)
>>> AA = A.reshape(3, 1)
>>> BB = B.reshape(3, 1)
>>> AA.shape
(3, 1)
>>> BB.shape
(3, 1)
>>> np.matmul(AA, np.transpose(BB))
array([[ 4, 5, 6],
[ 8, 10, 12],
[12, 15, 18]])
Using numpy.reshape works for me all the time.
Maybe you're stumbling on it because of your matrix's size.
A should be (3,1) dan B.transpose should be (1,3).
When using numpy.dot, both matrix should have the same inner size. In your case is (1). The inner should be 1 because the inner of AxA_transpose is (3,1)x(1,3). Result will be 3x3 matrix.
Do:
A_ = np.reshape(A,(1,-1)) # array (3,1)
B_ = np.reshape(B,(1,-1))
C = np.dot(A_,B_.T) # T for transpose

Matrix size in Python

a is a 2x2 matrix
b is a 2x1 matrix
c is a 1x2 matrix
But ... what kind of matrices d is?
import numpy as np
a= np.array([[1,2],[3,4]])
b= np.array([[1],[2]])
c= np.array([[1,2]])
d= np.array([1,2])
Variable explorer
The variable d is not a matrix but a row vector.
import numpy as np
a= np.array([[1,2],[3,4]])
b= np.array([[1],[2]])
c= np.array([[1,2]])
d= np.array([1,2])
print(a.shape, b.shape, c.shape, d.shape)
print(a.ndim, b.ndim, c.ndim, d.ndim)
outputs shapes:
(2, 2) (2, 1) (1, 2) (2,)
and dimensions:
2 2 2 1
The number of brackets indicate the number of dimensions, for example:
e = np.array([[[1,2]]])
outputs shape (1, 1, 2) and ndim 3 (so 3 dimensional).
It's a 1-dimensional array with 2 elements in it.
Check the output in the sandbox.

SciPy: Symmetric permutation of sparse CSR matrix

I'd like to symmetrically permute a sparse matrix, permuting rows and columns in the same way. For example, I would like to rotate the rows and columns, which takes:
1 2 3
0 1 0
0 0 1
to
1 0 0
0 1 0
2 3 1
In Octave or MATLAB, one can do this concisely with matrix indexing:
A = sparse([1 2 3; 0 1 0; 0 0 1]);
perm = [2 3 1];
Aperm = A(perm,perm);
I am interested in doing this in Python, with NumPy/SciPy. Here is an attempt:
#!/usr/bin/env python
import numpy as np
from scipy.sparse import csr_matrix
row = np.array([0, 0, 0, 1, 2])
col = np.array([0, 1, 2, 1, 2])
data = np.array([1, 2, 3, 1, 1])
A = csr_matrix((data, (row, col)), shape=(3, 3))
p = np.array([1, 2, 0])
#Aperm = A[p,p] # gives [1,1,1], the permuted diagonal
Aperm = A[:,p][p,:] # works, but more verbose
Is there a cleaner way to accomplish this sort of symmetric permutation of a matrix?
(I'm more interested in concise syntax than I am in performance)
In MATLAB
A(perm,perm)
is a block operation. In numpy A[perm,perm] selects elements on the diagonal.
A[perm[:,None], perm]
is the block indexing. The MATLAB diagonal requires something like sub2ind. What's concise in one is more verbose in the other, and v.v.
Actually numpy is using the same logic in both cases. It 'broadcasts' one index against the other, A (n,) against (n,) in the diagonal case, and (n,1) against (1,n) in the block case. The results are (n,) and (n,n) shaped.
This numpy indexing works with sparse matrices as well, though it isn't as fast. It actually uses matrix multiplication to do this sort of indexing - with an 'extractor' matrix based on the indices (maybe 2, M*A*M.T).
MATLAB's documentation about a permutation matrix:
https://www.mathworks.com/help/matlab/math/sparse-matrix-operations.html#f6-13070

combine numpy array "element-wise"

Currently I have two arrays: the shape of a1 is (5,4,6,3), the second one a2 is (5,4,6) and finally I want to get a merged array (5,4,6,4)
Currently I "for-loop" each (6,3) array and np.stack it with corresponding (6,1) to (6,4).
for i in range(a1.shape[0]):
for j in range(a1.shape[1]):
a = np.hstack((a1[i,j], a2[i,j].reshape(6,1)))
However, it's not pretty efficient if it's much bigger than 5*4.
Do you have a better way?
Is this what you want?
import numpy as np
a1 = np.ones((5, 4, 6, 3))
a2 = np.ones((5, 4, 6))
result = np.concatenate((a1, a2[..., np.newaxis]), axis=-1)
print(result.shape)
(5, 4, 6, 4)

Categories

Resources