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

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.

Related

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]])

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

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]]])

numpy roll along a single axis

I have a numpy array with binary values that I need to change in the following way: The value of every element must be shifted one column to the left but only within the same row. As an example, I have the following array:
>>> arr = np.array([[0,0,1,0],[1,0,0,0],[0,0,1,1]])
>>> arr
array([[0, 0, 1, 0],
[1, 0, 0, 0],
[0, 0, 1, 1]])
And it needs to be transformed to:
>>> arr
array([[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 1, 1, 0]])
I know that np.roll(arr,-1) would roll the values one cell to the left, but it doesn't seem to be able to roll them within the rows they belong to (i.e. the element on cell [1,0] goes to [0,3] instead of the desired [1,3]. Is there a way of doing this?
Thanks in advance.
roll accepts an axis parameter:
np.roll(arr,-1, axis=1)
array([[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 1, 1, 0]])

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