Home > Enterprise >  How to convert real coordinates to a 0-1 grid?
How to convert real coordinates to a 0-1 grid?

Time:03-09

I have a set of coordinates like this:

np.random.rand(5, 2) * 100
array([[70.89188827, 10.19794602],
       [97.59071239, 30.97320455],
       [66.47328843, 97.29316592],
       [20.86154854, 96.20304524],
       [96.56701376, 69.69812926]])

I would like to convert them to 0-1 matrix that would represent a tiles of 100x100 size where 1 is when the point (array row) is within a particular tile. How can I quickly do this?

CodePudding user response:

I'm confused about the question -- do you want a grid that is 0 everywhere except for where the points are (i.e. the values in the grid are either 0 or 1) or do you want a gradient map where the given coordinates are the peaks?

Assuming you want an array where all values are either 0 or 1, it looks like you're trying to use the 2-column array for indices; for the row [70.89188827 10.19794602] in the random array, you want the tile in the 70th row and 10th column (including zero-indexing) to have the value 1, right?

You could do something like this:

square_size = 100     # how long the side of your array should be. 
num_indices = 5       # How many indices to generate.

random_arr = np.random.rand(num_indices, 2) * square_size

# The random array must be made into integers to be used as indices.
random_arr = np.floor(random_arr).astype(int)

# Make the square array to use for tiles.
tile_array = np.zeros((square_size, square_size), dtype=int)

# For each value in random_arr, find that tile in tiles_array and make that tile = 1.
tile_array[random_arr[:, 0], random_arr[:, 1]] = 1

In this case, the row [70.89188827 10.19794602] in the random array you generated would become [70 10] after the flooring step, and then the tile in the 70th row (71st if you're counting from 1) and 10th column (11th if you're counting from 1) will become 1.

P.S. If you want the tile_array to be flipped so that the tile in the 70th column and 10th row becomes 1, you can add tile_array = tile_array.T at the end.

P.P.S. In answer to the 2nd question posted in the comments -- you could insert the following code after the random_arr = np.floor(random_arr).astype(int) line in the original code I posted. If there are any duplicated rows, those rows will be adjusted to refer to the tile in the next column. E.g. if there are two rows [10,13] in random_arr, the tiles corresponding to [10,13] and [10,14] will be 1. If the duplicated tile is at the end of a row, the 0th tile in the next row will be marked as 1.

Note that this method is very simplistic; if the adjusted tile is the same as a tile already in random_arr, it will not do something clever and mark the tile after that. E.g. say random_arr has the indices [10,13], [10,13], [10,14]. The duplicated [10,13] will be adjusted to be [10,14], but in this case, that does not change which tiles would have been marked anyway, since [10,14] is already in random_arr.

There is also almost definitely a better way to select duplicate rows than what I've done; I just don't know it.

# unique_rows_packed returns the actual rows in random_arr that are unique,
# as well as the indices of these rows. These are unpacked into 
# unique_rows and unique_rows_indices.

unique_rows_packed = np.unique(random_arr, True, axis=0)
unique_rows = unique_rows_packed[0]
unique_rows_indices = unique_rows_packed[1]

# Start with all row indices in random_arr and delete the rows which are unique rows.
# duplicate_rows then only includes the indices of duplicate rows.
indices_arr = np.arange(0, num_indices, 1)
duplicate_rows = np.delete(indices_arr, unique_rows_indices, axis=0)

# Get the values of the duplicate rows.
duplicate_row_vals = random_arr[duplicate_rows]

# Nudge duplicate row values.
for row in range(duplicate_row_vals.shape[0]):
    # check if duplicate row is for a tile at the end of a row (i.e. column number = square_size - 1).
    # If not, then add 1 to column number.
    orig_x, orig_y = duplicate_row_vals[row, 0], duplicate_row_vals[row, 1]

    if orig_y < square_size - 1:
        duplicate_row_vals[row, 1]  = 1

    # If tile is at end of row, then adjust the duplicated tile to equal
    # the 0th tile in the next row.
    else:
        duplicate_row_vals[row] = [orig_x   1, 0]

# Concatenate the unique rows values and adjusted duplicate row values to get the final indices.
random_arr = np.concatenate((unique_rows, duplicate_row_vals), axis=0)
  • Related