Python 将栅格上的总体转换为坐标,反之亦然

Python 将栅格上的总体转换为坐标,反之亦然,python,numpy,vectorization,Python,Numpy,Vectorization,对于生态项目,我需要在正方形网格世界上的两种人口表示形式之间来回切换: 表示法1:简单的网格(一个2d Numpy数组),其中每个单元格中的值对应于该单元格中的个体数。例如,对于3x3网格: grid = np.array( [[0, 1, 0], [0, 3, 1], [0, 0, 0]] ) 表示法2:二维Numpy数组,其中包含网格上每个个体的x、y坐标: coords = np.array( [[0, 1], [1, 1], [1

对于生态项目,我需要在正方形网格世界上的两种人口表示形式之间来回切换:

表示法1:简单的网格(一个2d Numpy数组),其中每个单元格中的值对应于该单元格中的个体数。例如,对于3x3网格:

grid = np.array(
    [[0, 1, 0],
     [0, 3, 1],
     [0, 0, 0]]
)
表示法2:二维Numpy数组,其中包含网格上每个个体的x、y坐标:

coords = np.array(
    [[0, 1],
     [1, 1],
     [1, 1],
     [1, 1],
     [1, 2]]
)
正如您所看到的,当一个单元格上有多个个体时,其坐标会重复。因此,
coords
具有形状(总体大小,2)

grid\u to\u coords()
coords\u to\u grid()
的当前实现都涉及for循环,如下所示,这大大降低了执行速度:

def grid_to_coords(grid):
    non_zero_pos = np.nonzero(grid)
    pop_size = grid.sum(keepdims=False)
    coords = np.zeros((int(pop_size), 2))
    offset = 0
    for i in range(len(non_zero_pos[0])):
        n_in_pos = int(grid[non_zero_pos[0][i], non_zero_pos[1][i]])
        for j in range(n_in_pos):
            coords[i + j + offset] = [non_zero_pos[0][i], non_zero_pos[1][i]]
        offset += j
    return pos

def coords_to_grid(coords, grid_dim):
    grid = np.zeros((grid_dim, grid_dim), dtype=np.int32)
    for x, y in coords:
        # Add a particle to the grid, making sure it is actually on the grid!
        x = max(0, min(x, grid_dim - 1))
        y = max(0, min(y, grid_dim - 1))
        grid[x, y] += 1
    return grid
我需要一种方法来矢量化这两个函数。你能帮忙吗?
非常感谢。

这太棒了,非常感谢。为了完整起见,我将提到我在处理网格边缘时所做的一个小更改:在调用np.unique()之后,我在coords_to_grid()中插入了以下行:unique=np.clip(unique,0,grid_dim-1)
import numpy as np

grid = np.array(
    [[0, 1, 0],
     [0, 3, 1],
     [0, 0, 0]]
)

coords = np.array(
    [[0, 1],
     [1, 1],
     [1, 1],
     [1, 1],
     [1, 2]]
)


def grid_to_coords(grid):
    """
    >>> grid_to_coords(grid)
    array([[0, 1],
           [1, 1],
           [1, 1],
           [1, 1],
           [1, 2]])
    """
    x, y = np.nonzero(grid) # x = [0 1 1]; y = [1 1 2]
    # np.c_[x, y] = [[0 1]
    #                [1 1]
    #                [1 2]]
    # grid[x, y] = [1 3 1]
    return np.c_[x, y].repeat(grid[x, y], axis=0)


def coords_to_grid(coords, grid_dim):
    """
    >>> coords_to_grid(coords, 3)
    array([[0, 1, 0],
           [0, 3, 1],
           [0, 0, 0]])
    """
    unique, counts = np.unique(coords, axis=0, return_counts=True)
    # unique = [[0 1]
    #           [1 1]
    #           [1 2]]
    # counts = [1 3 1]
    ret = np.zeros((grid_dim, grid_dim), dtype=int)
    ret[unique[:, 0], unique[:, 1]] = counts
    return ret