Multiply all pairs of rows in a Numpy array [duplicate] - python

This question already has an answer here:
How to compute the outer product of two matrices in numpy?
(1 answer)
Closed 4 years ago.
I have an MxN Numpy array. I'd like to take each row of the array and multiply it element-wise by each row of the array, resulting in an MxMxN numpy array of the products.
le_input = np.array([
[0, 0, 1],
[0, 1, 0]
])
le_expected_output = np.array([
[
[0, 0, 1],
[0, 0, 0]
],
[
[0, 0, 0],
[0, 1, 0]
]
])
I can of course do this with a for loop, and I've tried that, but I'm assuming there's a way faster way to do this within Numpy. Does anyone have any ideas?

You can use np.einsum:
np.einsum('ik,jk->ijk', le_input, le_input)
# array([[[0, 0, 1],
# [0, 0, 0]],
# [[0, 0, 0],
# [0, 1, 0]]])
Or create a new axis and use array's broadcasting property to calculate the outer product on the first dimension:
le_input[:,None] * le_input
# array([[[0, 0, 1],
# [0, 0, 0]],
# [[0, 0, 0],
# [0, 1, 0]]])

Related

Reshaping a matrix (numpy array) when matrices are multiplied on individual elements

I am trying to multiply each element of a 2x2 matrix say [1,1],[1,1] with a 2x2 Identity matrix. The problem is that numpy puts the whole identity matrix as a separate sub index which is not the result I need to evaluate it further, I want it to have 4 rows and 4 columns but when I reshape it to (4,4), it offsets the values and I get [1,0,1,0] on each row (consult the image for required and obtained results).
Thank you!
Image here
EDIT:
Thanks for the response and code.
I made a mistake formulating my question so I'll try one more time.
I have a matrix
I = [[1,0],[0,1]]
A = [
[4*I, 0*I],
[1*(-I), 1*I]
]
This should generate the result:
A = [
[4, 0, 0, 0],
[0, 4, 0, 0],
[-1, 0, 1, 0],
[0, -1, 0, 1]
]
Looks like you want the Kronecker product.
In [585]: np.kron(np.ones((2,2),int), np.eye(2,dtype=int))
Out[585]:
array([[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 1]])
You were try to make the array with repeated uses of the eye:
In [590]: np.array([I,I,I])
Out[590]:
array([[[1, 0],
[0, 1]],
[[1, 0],
[0, 1]],
[[1, 0],
[0, 1]]])
This is a (3,2,2), that's joining the eye on a new leading axis.
It is possible to transpose/reshape the (2,2,2,2) produced by np.array([[I,I],[I,I]]), but I'll you with the kron.

Numpy assignment of 3D array values using 2D index array

I have a 3D numpy array of zeros, with dimensions CxHxW (in this example, C=4, H=2, and W=3):
A = np.array([[[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0]]
[[0, 0, 0],
[0, 0, 0]]
[[0, 0, 0],
[0, 0, 0]]])
I also have a 2D array of indices, with dimensions HxW, such that every value in the array is a valid index between [0, C-1]
B = np.array([[2, 3, 0],
[3, 1, 2]])
Is there a fast way, using vectorization, to modify array A such that A[B[i][j]][i][j] = 1, for all valid i, j?
A = np.array([[[0, 0, 1],
[0, 0, 0]],
[[0, 0, 0],
[0, 1, 0]]
[[1, 0, 0],
[0, 0, 1]]
[[0, 1, 0],
[1, 0, 0]]])
Thank you!
It seems like you are looking for put_along_axis:
np.put_along_axis(A, B[None,...], 1, 0)
Note that the second argument is required to have the same number of dimensions as the first, which is why B[None,...] is used instead of B.

Merge three numpy arrays, keep largest value

I want to merge three numpy arrays, for example:
a = np.array([[0,0,1],[0,1,0],[1,0,0]])
b = np.array([[1,0,0],[0,1,0],[0,0,1]])
c = np.array([[0,1,0],[0,2,0],[0,1,0]])
a = array([[0, 0, 1],
[0, 1, 0],
[1, 0, 0]])
b = array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
c = array([[0, 1, 0],
[0, 2, 0],
[0, 1, 0]])
Desired result would be to overlay them but keep the largest value where multiple elements are not 0, like in the middle.
array([[1, 1, 1],
[0, 2, 0],
[1, 1, 1]])
I solved this by iterating over all elements with multiple if-conditions. Is there a more compact and more beautiful way to do this?
You can try of stacking arrays together in extra dimension with Numpy np.dstack method
and extract the maximum value specific to added dimension
# Stacking arrays together
d = np.dstack([a,b,c])
d.max(axis=2)
Out:
array([[1, 1, 1],
[0, 2, 0],
[1, 1, 1]])
NumPy's np.ufunc.reduce allows to apply a function cumulatively along a given axis. We can just concatenate the arrays and reduce with numpy.maximum to keep the accumulated elementwise maximum:
np.maximum.reduce([a,b,c])
array([[1, 1, 1],
[0, 2, 0],
[1, 1, 1]])

3D numpy array in Theano

I'm having a 3D NumpyArray which I want to through in a Keras Neural Network.
Because of one hot encoding the array became a 3D array.
[
[[0,1,0,0], [1,0,0,0]],
[[0,0,0,1], [1,1,0,0]],
[[0,0,1,0], [0,0,0,1]]
]
Since Keras can only compute 2D arrays, my question is, how can I reduce the dimensionality and use it into a sequencial keras NN?
I currently get the error:
TypeError: ('Bad input argument to theano function with name "D:\\Python27\\lib\\site-packages\\keras\\backend\\theano_backend.py:503" at index 0(0-based)', 'Wrong number of dimensions: expected 2, got 3 with shape (32L, 10L, 12L).')
You can use numpy.ndarray.flatten to make it into a 1D array. Example:
import numpy as np
a = np.array(
[
[[0, 1, 0, 0], [1, 0, 0, 0]],
[[0, 0, 0, 1], [1, 1, 0, 0]],
[[0, 0, 1, 0], [0, 0, 0, 1]]
]
)
a.flatten()
From this, if you want to split it by row, I'd recommend doing
import numpy as np
a = np.array(
[
[[0, 1, 0, 0], [1, 0, 0, 0]],
[[0, 0, 0, 1], [1, 1, 0, 0]],
[[0, 0, 1, 0], [0, 0, 0, 1]]
]
)
a = map(np.ndarray.flatten, a)

Finding largest indices of non-zero elements along each axis

I have a 3d numpy array. I'd like to find the largest x, y and z co-ordinates of non-zero element elements along each of the three axes of the array. How can I do that?
So for the example below x=1, y=2, z=1
array([[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
Get the indices of non-zero elements with np.nonzero and stack them up in columns with np.column_stack and finally find the max along the columns with .max(0). The implementation would look something like this -
np.column_stack((np.nonzero(A))).max(0)
Looks like there is a built-in function np.argwhere for getting indices of all non-zero elements stacked in a 2D array. Thus, you can simply do -
np.argwhere(A).max(0)
Sample run -
In [50]: A
Out[50]:
array([[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
In [51]: np.column_stack((np.nonzero(A))).max(0)
Out[51]: array([1, 2, 1])
In [52]: np.argwhere(A).max(0)
Out[52]: array([1, 2, 1])
Done using numpy.nonzero
>>> tuple(coords.max() for coords in numpy.nonzero(A))
(1, 2, 1)

Categories

Resources