I want to create an array made of arrays in Python with numpy
I'm trying to calcule the inverse of a matrix made by some other matrix using numpy method linalg.inv() but it calculates one inverse for each submatrix instead of a general inverse
for example, lets say I have:
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
i = np.array([[1, 0],
[0, 1]])
what I've tried is:
c = np.array([[a, i],
[i, b]])
what I want is
>> [[1, 2, 1, 0]
[3, 4, 0, 1]
[1, 0, 5, 6]
[0, 1, 7, 8]]
what I get is
>> [[[[1 2]
[3 4]]
[[1 0]
[0 1]]]
[[[1 0]
[0 1]]
[[5 6]
[7 8]]]]
You can use the np.block function, which can be used to assemble a block of matrices. You can do something like this,
np.block([[a,i],[i,b]])
Related
I have different sizes of arrays that each element is its index if it was flatten. Is there a way to print out every element per square going clockwise? I thought about slicing the arrays but that doesn't go clockwise and only prints one square and not all.
arr1 = np.array([[0, 1],[2, 3]])
arr2 = np.array([[0, 1, 2],[3, 4, 5]])
arr3 = np.array([[0, 1],[2, 3],[4, 5]])
print(arr1[0:2,0:2])
print()
print(arr2[0:2,0:2])
print()
print(arr3[0:2,0:2])
output:
[[0 1]
[2 3]]
[[0 1]
[3 4]]
[[0 1]
[2 3]]
Maybe this helps
import numpy as np
a = np.random.randint(0, 10, size=(7, 9))
print(a)
for i in range(a.shape[0]):
for j in range(a.shape[1]):
x = a[i:i+2, j:j+2]
if x.flatten().size == 4:
print(x) # every 2 by 2 array of 4 elements
m = x.copy() # copy x so not to be changed!
m[1] = m[1][::-1] # reverse row 1 elements
print(m.flatten()) # 1d array clockwise
from numpy.lib.stride_tricks import sliding_window_view
def zay_117(arr):
output = []
for row in sliding_window_view(arr, window_shape=(2,2)):
for sq in row:
output.append(np.hstack((sq[0, 0:2], sq[1, 0:2][::-1])).tolist())
return output
# zay_117(arr1)
# [[0, 1, 3, 2]]
# zay_117(arr2)
# [[0, 1, 4, 3], [1, 2, 5, 4]]
# zay_117(arr3)
# [[0, 1, 3, 2], [2, 3, 5, 4]]
I have some 4-dimensional numpy arrays for which the easiest visualisation is a matrix of arbitrary size (not necessarily square) in which each element is a 2x2 square matrix. I would like to standard matrix multiply (#) the 2x2 matrices of the large matrices elementwise (producing another matrix of the same dimension of 2x2 matrices). The eventual hope is to parallelize this process using CuPy so I want to do this without resorting to looping over every element of the bigger matrix.
Any help would be appreciated.
Example of what I mean:
x = np.array([[ [[1,0], [0, 1]], [[2,2], [2, 1]] ]])
y = np.array([[ [[1,3], [0, 1]], [[2,0], [0, 2]] ]])
xy = np.array([[ [[1,3], [0, 1]], [[4,4], [4, 2]] ]])
[[ [[1, 0], [[2, 2] x [[ [[1, 3], [[2, 0]
[0, 1]] , [2, 1]] ]] [0, 1]] , [0, 2]] ]]
=> [[ [[1, 3], [[4, 4]
[0, 1]] , [4, 2]] ]]
In this example the 2 'large' matrices are 1x2 matrices where each of the 2 elements are 2x2 matrices. I have tried to lay it out in a manner that makes it clear what is going on as well as using standard 4d numpy arrays.
Edited in line with comments.
As Homer512 stated in a comment, np.matmul, aka the # operator, will handle this scenario (see the numpy docs). You will need to make sure your 2 x 2 matrices are in the last dimensions.
import numpy as np
a1 = np.array([[1, 0], [0, 1]])
a2 = np.array([[2, 2], [2, 1]])
a = np.array([a1, a2])
b1 = [[1, 3], [0, 1]]
b2 = [[2, 0], [0, 2]]
b = np.array([b1, b2])
x = np.array([a, b])
print(a # b)
Output:
[[[1 3]
[0 1]]
[[4 4]
[4 2]]]
I'm new with Python and programming in general.
I want to create a function that multiplies two np.array of the same size and get their scalar value, for example:
matrix_1 = np.array([[1, 1], [0, 1], [1, 0]])
matrix_2 = np.array([[1, 2], [1, 1], [0, 0]])
I want to get 4 as output ((1 * 1) + (1 * 2) + (0 * 1) + (1 * 1) + (1 * 0) + (0 * 0))
Thanks!
Multiply two matrices element-wise
Sum all the elements
multiplied_matrix = np.multiply(matrix_1,matrix_2)
sum_of_elements = np.sum(multiplied_matrix)
print(sum_of_elements) # 4
Or in one shot:
print(np.sum(np.multiply(matrix_1, matrix_2))) # 4
You can make use of np.multiply() to multiply the two arrays elementwise, then we call np.sum() on this matrix. So we thus can calculate the result with:
np.multiply(matrix_1, matrix_2).sum()
For your given sample matrix, we thus obtain:
>>> matrix_1 = np.array([[1, 1], [0, 1], [1, 0]])
>>> matrix_2 = np.array([[1, 2], [1, 1], [0, 0]])
>>> np.multiply(matrix_1, matrix_2)
array([[1, 2],
[0, 1],
[0, 0]])
>>> np.multiply(matrix_1, matrix_2).sum()
4
There are a couple of ways to do it (Frobenius inner product) using numpy, e.g.
np.sum(A * B)
np.dot(A.flatten(), B.flatten())
np.trace(np.dot(A, B.T))
np.einsum('ij,ij', A, B)
One recommended way is using numpy.einsum, since it can be adapted to not only matrices but also multiway arrays (i.e., tensors).
Matrices of the same size
Take the matrices what you give as an example,
>>> import numpy as np
>>> matrix_1 = np.array([[1, 1], [0, 1], [1, 0]])
>>> matrix_2 = np.array([[1, 2], [1, 1], [0, 0]])
then, we have
>>> np.einsum('ij, ij ->', matrix_1, matrix_2)
4
Vectors of the same size
An example like this:
>>> vector_1 = np.array([1, 2, 3])
>>> vector_2 = np.array([2, 3, 4])
>>> np.einsum('i, i ->', vector_1, vector_2)
20
Tensors of the same size
Take three-way arrays (i.e., third-order tensors) as an example,
>>> tensor_1 = np.array([[[1, 2], [3, 4]], [[2, 3], [4, 5]], [[3, 4], [5, 6]]])
>>> print(tensor_1)
[[[1 2]
[3 4]]
[[2 3]
[4 5]]
[[3 4]
[5 6]]]
>>> tensor_2 = np.array([[[2, 3], [4, 5]], [[3, 4], [5, 6]], [[6, 7], [8, 9]]])
>>> print(tensor_2)
[[[2 3]
[4 5]]
[[3 4]
[5 6]]
[[6 7]
[8 9]]]
then, we have
>>> np.einsum('ijk, ijk ->', tensor_1, tensor_2)
248
For more usage about numpy.einsum, I recommend:
Understanding NumPy's einsum
I have this set of equations I want to perform:
x = np.linspace(0, 2, 3)
y = np.linspace(x, x+2, 3)
I then want to populate the 2D array with a calculation that does:
a = 2*x + y
So for example, given an array:
x = [0, 1, 2]
Then, the array y is:
y = [[0, 1, 2],
[1, 2, 3],
[2, 3, 4]]
When I perform the operation a = 2*x + y I should get the array:
a = [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
How do I do this, keeping in mind I want to perform this operation quickly for array of size up to 10000x10000 (or larger)?
Or do your code adding two Ts:
print((2*x+y.T).T)
Output:
[[0 1 2]
[3 4 5]
[6 7 8]]
I want to rotate an array but not like a basic matrix rotation. If I have a 3x3 array, I want each of the cells to turn around the central cell.
Here is a 3x3 array:
import numpy as np
tab = np.array([[1,2,3],[4,5,6],[7,8,9]])
[[1 2 3]
[4 5 6]
[7 8 9]]
I want for instance to rotate it by 45 degrees:
[[2 3 6]
[1 5 9]
[4 7 8]]
I can't use scipy.ndimage.interpolation.rotate(tab,45) because it applies a basic matrix rotation and this is not what I want.
import numpy as np
from scipy import ndimage
tab = np.array([[1,2,3],[4,5,6],[7,8,9]])
ndimage.interpolation.rotate(tab,45)
[[0 0 0 0]
[0 2 6 0]
[0 4 8 0]
[0 0 0 0]]
Does anybody know how this can be achieved?
Your almost had it just use this:
ndimage.interpolation.rotate(tab,45,reshape=False,mode='nearest')
the thing is you need to force the method to not reshape your matrix and also use nearest number as fill in the blank instead of zeros.
The problem with zeros is that some numbers (the ones in the corners) become out of boundaries when you rotate the matrix so you need to "predict" those missing corners by nearest like precised here
output:
[[2 3 6]
[1 5 9]
[4 7 8]]
rotate it again it gives:
[[3 6 9]
[2 5 8]
[1 4 7]]
etc..
If you only want to use it on 3x3 arrays, a simple solution would be to list the indexes in a clockwise/anticlockwise order (eg: [(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (2, 1), (2, 0), (1, 0)]), then for the rotations you just shift the values according to the list indexes (by degrees/45° places).
You can do this by creating a pair of index arrays (in which a rotation can be seen visually):
i = np.array([
[0, 0, 1],
[0, 1, 2],
[1, 2, 2]
])
j = np.array([
[1, 2, 2],
[0, 1, 2],
[0, 0, 1]
])
Which then works as desired:
>>> tab = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> tab[i,j]
array([[2, 3, 6],
[1, 5, 9],
[4, 7, 8]])
This is essentially a vectorized implementation of Balázs Kovacsics' solution, which should be faster than the ndimage solution
To rotate twice, you can use either
>>> tab[i,j][i,j]
array([[3, 6, 9],
[2, 5, 8],
[1, 4, 7]])
>>> i2 = i[i,j]
>>> j2 = j[i,j]
>>> tab[i2,j2]
array([[3, 6, 9],
[2, 5, 8],
[1, 4, 7]])