finding every squares value in array - python

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

Related

Find the row index number of an array in a 2D numpy array

If I have a 2D numpy array A:
[[6 9 6]
[1 1 2]
[8 7 3]]
And I have access to array [1 1 2]. Clearly, [1 1 2] belongs to index 1 of array A. But how do I do this?
Access the second row using the following operator:
import numpy as np
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
row = [1, 1, 2]
i = np.where(np.all(a==row, axis=1))
print(i[0][0])
np.where will return a tuple of indices (lists), which is why you need to use the operators [0][0] consecutively in order to obtain an int.
One option:
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
b = np.array([1, 1, 2])
np.nonzero((a == b).all(1))[0]
output: [1]
arr1 = [[6,9,6],[1,1,2],[8,7,3]]
ind = arr1.index([1,1,2])
Output:
ind = 1
EDIT for 2D np.array:
arr1 = np.array([[6,9,6],[1,1,2],[8,7,3]])
ind = [l for l in range(len(arr1)) if (arr1[l,:] == np.array([1,1,2])).all()]
import numpy as np
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
b = np.array([1, 1, 2])
[x for x,y in enumerate(a) if (y==b).all()] # here enumerate will keep the track of index
#output
[1]

How to construct a matrix that contains all pairs of rows of a matrix in tensorflow

I need to construct a matrix z that would contain combinations of pairs of rows of a matrix x.
x = tf.constant([[1, 3],
[2, 4],
[0, 2],
[0, 1]], dtype=tf.int32)
z=[[[1,2],
[1,0],
[1,0],
[2,0],
[2,0],
[0,0]],
[3,4],
[3,2],
[3,1],
[4,2],
[4,1],
[2,1]]]
It pairs each value with the rest of the values on that row.
I could not find any function or come up with a good idea to do that.
Update 1
So I need the final shape be 2*6*2 like the z above.
Unfortunately, it's a bit more complex than one would like using tensorflow operators only. I would go with creating the indices for all combinations with a while_loop then use tf.gather to collect values:
import tensorflow as tf
x = tf.constant([[1, 3],
[2, 4],
[3, 2],
[0, 1]], dtype=tf.int32)
m = tf.constant([], shape=(0,2), dtype=tf.int32)
_, idxs = tf.while_loop(
lambda i, m: i < tf.shape(x)[0] - 1,
lambda i, m: (i + 1, tf.concat([m, tf.stack([tf.tile([i], (tf.shape(x)[0] - 1 - i,)), tf.range(i + 1, tf.shape(x)[0])], axis=1)], axis=0)),
loop_vars=(0, m),
shape_invariants=(tf.TensorShape([]), tf.TensorShape([None, 2])))
z = tf.reshape(tf.transpose(tf.gather(x, idxs), (2,0,1)), (-1, 2))
# <tf.Tensor: shape=(12, 2), dtype=int32, numpy=
# array([[1, 2],
# [1, 3],
# [1, 0],
# [2, 3],
# [2, 0],
# [3, 0],
# [3, 4],
# [3, 2],
# [3, 1],
# [4, 2],
# [4, 1],
# [2, 1]])>
This should work in both TF1 and TF2.
If the length of x is known in advance, you don't need the while_loop and could simply precompute the indices in python then place them in a constant.
Here is a way to do that without a loop:
import tensorflow as tf
x = tf.constant([[1, 3],
[2, 4],
[0, 2],
[0, 1]], dtype=tf.int32)
# Number of rows
n = tf.shape(x)[0]
# Grid of indices
ri = tf.range(0, n - 1)
rj = ri + 1
ii, jj = tf.meshgrid(ri, rj, indexing='ij')
# Stack together
grid = tf.stack([ii, jj], axis=-1)
# Get upper triangular part
m = ii < jj
idx = tf.boolean_mask(grid, m)
# Get values
g = tf.gather(x, idx, axis=0)
# Rearrange result
result = tf.transpose(g, [2, 0, 1])
print(result.numpy())
# [[[1 2]
# [1 0]
# [1 0]
# [2 0]
# [2 0]
# [0 0]]
#
# [[3 4]
# [3 2]
# [3 1]
# [4 2]
# [4 1]
# [2 1]]]

How to get the scalar multiplication between 2 matrices?

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

Populating a 2D array to calculate a function of two linspaces

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

how to calculate a 2D array with numpy mask

I have a 2 dimension array and based if the value is greater than 0 I want to do a operation (example with x+1).
In plain python something like this:
a = [[2,5], [4,0], [0,2]]
for x in range(3):
for y in range(2):
if a[x][y] > 0:
a[x][y] = a[x][y] + 1
Result for a is [[3, 6], [5, 0], [0, 3]]. This is what I want.
Now I want to prevent the nested loop and tried with numpy something like this:
a = np.array([[2,5], [4,0], [0,2]])
mask = (a > 0)
a[mask] + 1
The result is now a 1 dimension and the shape of the array [3 6 5 3]. How can I do this operation and don't loose the dimension like in the plain python example before?
If a is a numpy array, you can simply do -
a[a>0] +=1
Sample run -
In [335]: a = np.array([[2,5], [4,0], [0,2]])
In [336]: a
Out[336]:
array([[2, 5],
[4, 0],
[0, 2]])
In [337]: a[a>0] +=1
In [338]: a
Out[338]:
array([[3, 6],
[5, 0],
[0, 3]])

Categories