Numpy "Place Object" in Array - python

I have a program where I am trying to generate outputs based on a few IO's--like these two IOs.
The program recognizes objects in the grids, and it represents the grids as numpy arrays. Is there a built in numpy function, or elegant solution, to 'inserting' an object into a numpy array?
Ex: if it recognizes a square object, like [[1, 1], [1, 1]], and I have a grid [[0, 0, 0], [0, 0, 0], [0, 0, 0]], how can I insert the object into the grid so it becomes [[0, 1, 1], [0, 1, 1], [0, 0, 0]] (but for any object inserted at any index)?

There is no way other than knowing the indices at which to change the value of your 2-D numpy array.
So if your grid is a 2-D array of zeros like:
grid = np.zeros((10, 10))
Then you can use a tuple of indices tuples (x, y), each identifying a cell of your grid at which you want to change the grid value:
indices = ((x1, y1), (x2, y2), ..., (xn, yn))
then you can use it to assign values in your 2-D numpy array like so:
grid[indices] = 1

Related

diagonalize multiple vectors using numpy

Say I have a matrix of shape (2,3), I need to diagonalize the 3-elements vector into matrix of shape (3,3), for all the 2 vectors at once. That is, I need to return matrix with shape (2,3,3). How can I do that with Numpy elegantly ?
given data = np.array([[1,2,3],[4,5,6]])
i want the result [[[1,0,0],
[0,2,0],
[0,0,3]],
[[4,0,0],
[0,5,0],
[0,0,6]]]
Thanks
tl;dr, my one-liner: mydiag=np.vectorize(np.diag, signature='(n)->(n,n)')
I suppose here that by "diagonalize" you mean "applying np.diag".
Which, as a teacher of linear algebra, tickles me a bit. Since "diagonalizing" has a specific meaning, which is not that (it is computing eigen vectors and values, and from there, writing M=P⁻¹ΛP. Which you cannot do from the inputs you have).
So, I suppose that if input matrix is
[[1, 2, 3],
[9, 8, 7]]
The output matrix you want is
[[[1, 0, 0],
[0, 2, 0],
[0, 0, 3]],
[[9, 0, 0],
[0, 8, 0],
[0, 0, 7]]]
If not, you can ignore this answer [Edit: in the meantime, you explained exactly that. So yo may continue to read].
There are many way to do that.
My one liner would be
mydiag=np.vectorize(np.diag, signature='(n)->(n,n)')
Which build a new functions which does what you want (it interprets the input as a list of 1D-array, call np.diag of each of them, to get a 2D-array, and put each 2D-array in a numpy array, thus getting a 3D-array)
Then, you just call mydiag(M)
One advantage of vectorize, is that it uses numpy broadcasting. In other words, the loops are executed in C, not in python. In yet other words, it is faster. Well it is supposed to be (on small matrix, it is in fact slower than Michael's method - in comment; on large matrix, it is has the exact same speed. Which is frustrating, since einsum doc itself specify that it sacrifices broadcasting).
Plus, it is a one-liner, which has no other interest than bragging on forums. But well, here we are.
Here is one way with indexing:
out = np.zeros(data.shape+(data.shape[-1],), dtype=data.dtype)
x,y = np.indices(data.shape).reshape(2, -1)
out[x,y,y] = data.ravel()
output:
array([[[1, 0, 0],
[0, 2, 0],
[0, 0, 3]],
[[4, 0, 0],
[0, 5, 0],
[0, 0, 6]]])
We use array indexing to precisely grab those elements that are on the diagonal. Note that array indexing allows broadcasting between the indices, so we have index1 contain the index of the array, and index2 contain the index of the diagonal element.
index1 = np.arange(2)[:, None] # 2 is the number of arrays
index2 = np.arange(3)[None, :] # 3 is the square size of each matrix
result = np.zeros((2, 3, 3))
result[index1, index2, index2] = data

Trying to extract a patch given 8 points from NumPy array

I have an array which looks like this
boxes = [268,885,426,865,406,707,248,727]
It's a collection of (x,y) points. If I plot this using this function:
def draw_boxes_on_image_mod(image, boxes):
image_copy = image.copy()
image_copy = np.array(image_copy)
cv2.line(image_copy, (boxes[0],boxes[1]),(boxes[2],boxes[3]),(0,255,255),2)
cv2.line(image_copy, (boxes[4], boxes[5]),(boxes[6],boxes[7]),(0,255,255),2)
cv2.line(image_copy, (boxes[0],boxes[1]),(boxes[6],boxes[7]),(0,255,255),2)
cv2.line(image_copy, (boxes[4], boxes[5]),(boxes[2],boxes[3]),(0,255,255),2)
scipy. misc.imsave('/home/ryan/TEST.png', image_copy)
return image_copy
I get an image with a rectangle drawn on the part of the image I'm interested in, But what I want is to extract that portion and convert it into an image.
I was thinking of using NumPy indexing to achieve this but
image = image[268:426]
I am finding it difficult to understand how to index the (x,y) values together.
Any suggestions would be really helpful.Thanks in advance.
When you just call A[1:3] all you are asking for are the rows 1 and 2, the rows including 1 and stopping before 3, so you must take into account columns as well to get the exact subsection you need.
You can do this in numpy by stating the range of the rows and columns, the subsection of the array you want will start at a row and end at row + m as well as starting at a column and ending at column + n
For example take
A = np.array([[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]])
We want just the values in the middle set to 1, so we select them with
Asub = A[1:3,1:3]
To get
[[1 1]
[1 1]]

Python vtkInterface0.9.3 library examples not working

I found out about vtkInterface, a python vtk wrapper that facilitates vtk plotting.
Trying to run their first example, under Initialize from Numpy Arrays in this page: vtkInterface.PolyData, by simply running the code as is, and it results in a gray render window with nothing in it.
Some of the other examples do work but this is exactly the thing that I need at the moment and was wondering if anybody has tried it and knows what might be wrong.
Example Code:
import numpy as np
import vtkInterface
# mesh points
vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0]])
# mesh faces
faces = np.hstack([[4, 0, 1, 2, 3], # square
[3, 0, 1, 4], # triangle
[3, 1, 2, 4]]) # triangle
surf = vtkInterface.PolyData(vertices, faces)
# plot each face with a different color
surf.Plot(scalars=np.arange(3))
The example is wrong. It lacks a fifth point. For example this will work.
vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[0.5, 0.5, -1]])
Explanation: In VTK, faces are encoded in the following way:
face_j = [ n, i_0, i_1, ..., i_n ]
Here, n is the number of points per face, and i_k are the indices of the points in the vertex-array. The face is formed by connecting the points vertices[i_k] with k in range(0,n). A list of faces is created by simply concatenating the single face specifications:
np.hstack([face_0, face_1, ..., face_j, ...])
The advantage of this encoding is that the number of points used per face, n, can vary. So a mesh can consist of lines, triangles, quads, etc.
In the example, the vertex with id 4 is used in the second and third face. So vertices is required to consist of at least five entries. Surprisingly, the sample doesn't crash, as VTK almost certainly would if some faces were accessing non-existing points.

Replace numpy cell with values from second array based on a condition

I have two images, img1 and img2. I'm trying to find everywhere in img1 that the color [0,204,204] occurs and replace it with whatever is in img2 in the same place. I can use np.where() to find the places where that color occurs and replace it with a different color directly:
img1[np.where((img1==[0,204,204]).all(axis=2))] = [255,255,0]
I'm unsure how to grab the indices of these cells as the shape of the images are 5070000 with 3 dimensions, so, I can't display the array's effectively. Looking over the numpy documentation, I think I can do something like:
img2[img1[img1==[0,204,204]]]
to get the indices of img1 where that color occurs and then call the same array position from img2, but, I can't seem to get this syntax correct. Help?
If I understand correctly, you can use the following:
img1[np.where((img1==[0,204,204]).all(axis=2))] = img2[np.where((img1==[0,204,204]).all(axis=2))]
This works because the syntax you had originally (np.where((img1==[0,204,204]).all(axis=2))) already returns the indices you are looking for
Example (on a small array):
img1 = np.array([[[0,204,204],[0,0,0],[1,2,3]]])
array([[[ 0, 204, 204],
[ 0, 0, 0],
[ 1, 2, 3]]])
img2 = np.array([[[0,1,2],[1,1,1],[2,7,3]]])
array([[[0, 1, 2],
[1, 1, 1],
[2, 7, 3]]])
img1[np.where((img1==[0,204,204]).all(axis=2))] = img2[np.where((img1==[0,204,204]).all(axis=2))]
>>> img1
array([[[0, 1, 2],
[0, 0, 0],
[1, 2, 3]]])

How can I make an 8by8 grid in Python and then be able to move a counter around it?

I need to make an 8by8 grid on python to form the basis of a game I am making. I then need to be able to move a counter around this grid. Thanks
Firstly clarify what exactly is this counter?
To address the grid, python lets you have multi-dimensional lists (list of lists)
Example:
# A 4x4 grid with all values to zero
grid = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
# It doesn't have to be numbers it can be any object
# Accessing the grid
for y in range(len(grid)): # Goes through each row
for x in range(len(grid[y])): # Goes through each column in the row
grid[y][x] # This gets the value in y-row, x-column
But if you are working with 2D data structure (or higher), I recommend numpy.
Numpy offers easy use of multi-dimensional lists (or arrays as they are called)
import numpy as np
grid = np.zeros((4,4)) # np.zeros just fills the array with zeros
# (4,4) is the shape (4x4 = (4,4), 4x4x4 = (4,4,4) and so on)
# The grid can be accessed the same way as above
Hope this helps if not well then I guess we need more details

Categories