【问题标题】:Optimized coordinates selection in 2D numpy array优化 2D numpy 数组中的坐标选择
【发布时间】:2022-01-14 22:02:20
【问题描述】:

我有一个 numpy 坐标数组。我想在 Xmin 和 Xmax 之间以及 Ymin 和 Ymax 之间进行选择。

这是我的代码:

grid = np.random.randint(2, size=81).reshape(9,9)
List_of_coordinates = np.argwhere(grid == 0)
Xmin, Xmax, Ymin, Ymax = 0,3,6,9
List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 1] >= Ymin]
List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 1] < Ymax]
List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 0] >= Xmin]
List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 0] < Xmax]

有没有更快的方法?

【问题讨论】:

  • 先切片再加分钟np.argwhere(grid[Xmin:Xmax, Ymin:Ymax] == 0)+[Xmin,Ymin]?我不知道这是否通常更快。 argwhere 的计算更少,比较更少,但总和更多。

标签: python numpy optimization sudoku


【解决方案1】:

首先对网格进行切片,您将获得相对于切片开头的索引,然后添加切片的开头以返回绝对坐标:

List_of_coordinates = (np.argwhere(grid[Xmin:Xmax,Ymin:Ymax] == 0)
                       +np.array([Xmin,Ymin]))

例子

网格:

array([[0, 1, 0, 0, 0, 0, 0, 1, 1],
       [1, 0, 1, 0, 1, 0, 1, 0, 0],
       [0, 1, 0, 1, 0, 1, 0, 0, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 0, 0, 1, 0, 0],
       [1, 0, 0, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 1, 0, 1],
       [1, 1, 0, 1, 1, 1, 1, 1, 0],
       [1, 0, 1, 0, 1, 0, 1, 0, 0]])

切片:

array([[0, 1, 1],
       [1, 0, 0],
       [0, 0, 1]])

0 的坐标:

array([[0, 6],
       [1, 7],
       [1, 8],
       [2, 6],
       [2, 7]])

【讨论】:

    【解决方案2】:

    您可以再次使用argwhere

    import numpy as np
    grid = np.random.randint(2, size=81).reshape(9,9)
    List_of_coordinates = np.argwhere(grid == 0)
    Xmin, Xmax, Ymin, Ymax = 0,3,6,9
    # select coordinates between Xmin and Xmax and Ymin and Ymax
    coordinates = np.argwhere(
    np.logical_and(List_of_coordinates[:,0] >= Xmin, List_of_coordinates[:,0] <= Xmax) &
    np.logical_and(List_of_coordinates[:,1] >= Ymin, List_of_coordinates[:,1] <= Ymax)
    )
    

    【讨论】:

    • 在此处使用“argwhere”不会使任何事情变得更快。它甚至使事情变得更加复杂,因为您获得的不是坐标而是List_of_coordinates 的索引。
    【解决方案3】:

    我(微)对您的解决方案、您的解决方案的优化版本和@mozway 的方法进行了基准测试(我没有包括@Mohammad 的答案,因为输出不同,第一个结果与优化后的原始结果大致相同)更大的示例数据。在 2 核 google colab 实例上运行。

    import numpy as np
    
    grid = np.random.randint(2, size=(1000,1000))
    Xmin, Xmax, Ymin, Ymax = 0,300,600,900
    
    %%timeit
    List_of_coordinates = np.argwhere(grid == 0)
    List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 1] >= Ymin]
    List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 1] < Ymax]
    List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 0] >= Xmin]
    List_of_coordinates = List_of_coordinates[List_of_coordinates[:, 0] < Xmax]
    List_of_coordinates
    

    原解决方案10 loops, best of 5: 30.1 ms per loop

    %%timeit
    List_of_coordinates = np.argwhere(grid == 0)
    LoC = List_of_coordinates[
        (List_of_coordinates[:, 1] >= Ymin) &
        (List_of_coordinates[:, 1] < Ymax) &
        (List_of_coordinates[:, 0] >= Xmin) &
        (List_of_coordinates[:, 0] < Xmax)               
    ]
    LoC
    

    优化原版100 loops, best of 5: 19.4 ms per loop

    %%timeit
    LoC = np.argwhere(grid[Xmin:Xmax, Ymin:Ymax] == 0) + np.array([Xmin,Ymin])
    LoC
    

    @mozway 的解决方案1000 loops, best of 5: 1.69 ms per loop

    【讨论】:

      猜你喜欢
      • 2015-10-26
      • 2019-07-10
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 2020-09-16
      相关资源
      最近更新 更多