【问题标题】:Random sampling of non-adjacent cells in a pixel grid像素网格中非相邻单元的随机采样
【发布时间】:2015-07-21 21:36:10
【问题描述】:

假设我们有一个n*n 网格。我们想选择这个网格中不相邻的k << n 随机单元格。如果我们用一个包含01 的二维 Numpy 数组来模拟这个网格,那么在 Numpy/Python 中最有效的方法是什么?

有效示例:

无效示例:

【问题讨论】:

  • 你想从哪个发行版中提取?您是否想要来自所有非相邻像素的 k 元组的空间中的统一样本,因为这些类型的组合采样问题可能非常困难(例如,具有固定行和列总和的采样矩阵)即使它们看起来乍一看很容易。
  • @Mr.F 我正在寻找制服样品。我不是在寻找所有的 k 元组。只需一个 k 元组的非相邻像素就可以了。
  • 如果网格中的单元格真的很稀疏,那么我只会进行拒绝抽样。通过均匀采样生成一些候选点,然后检查它们是否相邻,重复直到找到一组有效的点。您可以对稀疏数据(即点坐标)进行此检查,而不是检查完整的 n*n 网格。
  • 但它是 all 这样的 k 元组的 空间,当你想要进行平局时你必须描述(尽管在这种情况下它似乎有可能一次按顺序对一个像素进行采样,然后将其边界消隐,最终可能会产生统一的 k 元组。
  • 我也在考虑这种顺序采样。那是我的第一个选择。同时,我想知道是否有更有效的方法来做到这一点。

标签: python numpy random-sample


【解决方案1】:

这是拒绝抽样的简单实现。可能有比query_pairs 更快的方法来进行邻接检查(在这种情况下也会检查冲突),因为您只想测试是否至少有一对在此距离阈值内。

import numpy as np
from scipy.spatial import cKDTree as kdtree

n = 100
k = 50

valid = False

while not valid:
    # generate k grid indices
    coords_flat = np.random.random_integers(0, n ** 2 - 1, size=k)
    coords = np.unravel_index(coords_flat, dims=(n, n))
    # test there are no adjacent cells
    transposed = np.transpose(coords)
    valid = len(kdtree(transposed).query_pairs(1.0)) == 0

print(coords)

看看结果:

import matplotlib.pyplot as plt
grid = np.zeros((n, n), dtype=np.bool)
grid[coords] = True
plt.imshow(grid)
plt.savefig('result.png')

【讨论】:

  • 您的拒绝抽样算法似乎不起作用。我认为valid = len(kdtree(coords).query_pairs(1.0)) == 0 可能没有做到这里的意思。尝试query_pairs(10) 或其他大于 1 的数字...您会发现它不会产生所需的结果。
  • 感谢您指出这一点。问题是数据应该被转置:kdtree 将输入视为两个 50 维数据点。我已经更新了代码。
【解决方案2】:

我看到,这已经是一个公认的答案,但这是一项具有挑战性的任务,所以我解决了以下问题并且我很喜欢它,因此我对这个问题给予了 upvote :):

import numpy as np

xy = []

x = np.random.randint(0,5)
y = np.random.randint(0,5)

xy.append((x,y))

while True:

    x = np.random.randint(0,5)
    y = np.random.randint(0,5)

    for ii,i in enumerate(xy):    
        if x in [i[0]-1, i[0], i[0]+1]:
            if x == i[0]:
                if y in [i[1]-1, i[1], i[1]+1]:
                    break    
                else:
                    if ii == len(xy) - 1:
                        xy.append((x,y))
                        break
            elif y == i[1]:
                break
        elif ii == len(xy) - 1:
            xy.append((x,y))
            break

    if len(xy) == 3:
        break

for cords in xy:
    print cords

sq =np.zeros((5,5))

for cords in xy:
    sq[cords] = 1

print sq    

输出:

(1, 0)
(4, 4)
(4, 1)
[[ 0.  0.  0.  0.  0.]
 [ 1.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  1.]]

它总是提供非相邻单元格的随机组合。 好好享受! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2022-01-25
    相关资源
    最近更新 更多