在2D数组和顺序像素中创建移动窗口的最佳方法是什么

时间:2013-05-24 21:02:25

标签: python numpy

我是Python的新手,需要对它进行一些棘手的2D数组操作。我不确定最好的方法。

基本上,我从一个0到1之间的值数组开始。

我需要有一个移动的2x2窗口应用于2D阵列,(编辑:阵列是2D图像;即说200x200像素左右),在每个2x2窗口内,分配值1-4,相反,根据数组值权重(即2x2中的最小单元格变为4,然后下一个最小单元格变为3,等等)

我可以看到如何通过嵌套循环提取我的2x2窗口;那是最好的方式吗?

更为棘手的是如何进行订购任务。

我想在我的窗口子数组上迭代使用numpy.where(subarray.min),但我看不到如何在返回的返回位置获取!我不确定没有更好的方法来解决这个问题。

么?指示如何使用NumPy进行复杂,凌乱的数组操作?

2 个答案:

答案 0 :(得分:0)

所以你开始使用这样的数组:

In [1]: import numpy as np

In [2]: a = np.arange(20).reshape((10,-1))

In [3]: a
Out[3]: 
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17],
       [18, 19]])

我认为您要找的是reshapeargsort

使用reshape成员函数,您可以在不更改序列的情况下更改形状:

In [4]: a.reshape((-1,4))
Out[4]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19]])

重塑需要一个元组。我喜欢将其视为(行数,数量或列数)。在这种情况下,( - 1,4)表示:使用4列(因此每行包含四个数字),并根据数据量计算行数。

使用argsort,您可以获得所需的数组。

In [2]: import numpy as np

In [3]: d = np.random.random((10, 2)).reshape((-1,4))

In [4]: d
Out[4]: 
array([[ 0.65945195,  0.1907593 ,  0.1630845 ,  0.76949532],
       [ 0.90823488,  0.71518689,  0.38422877,  0.77824007],
       [ 0.31453967,  0.76592537,  0.5871099 ,  0.09306465],
       [ 0.38251335,  0.97461878,  0.97562622,  0.87532202],
       [ 0.12358359,  0.20323007,  0.397975  ,  0.615806  ]])


In [7]: e = np.array([4-np.argsort(r) for r in d])

In [8]: e
Out[8]: 
array([[2, 3, 4, 1],
       [2, 3, 1, 4],
       [1, 4, 2, 3],
       [4, 1, 3, 2],
       [4, 3, 2, 1]])

如您所见,每行现在都有所需的索引。让我们回顾第7行从内到外做的事情:

  • for r in d:迭代d。
  • 中的所有行
  • 4 - np.argsort(r):argsort会在0-3范围内创建索引。所以我们从4中减去它以得到4-1的逆范围。在numpy数组中,对每个元素进行操作,因此4 - np.array([2, 1, 0, 3])的行为类似于np.array([4,4,4,4]) - np.array([2, 1, 0, 3])
  • []:包含在方括号之间的前一行使其成为列表理解,这就像一个非常快速且紧凑的for循环返回列表。
  • np.array:数组列表合并为一个大数组。

然后使用另一个重塑,将数据恢复为原始形状

In [9]: e.reshape((-1,2))
Out[9]: 
array([[2, 3],
       [4, 1],
       [2, 3],
       [1, 4],
       [1, 4],
       [2, 3],
       [4, 1],
       [3, 2],
       [4, 3],
       [2, 1]])

修改

根据您的评论,您可以执行以下操作。假设你有一个2D矩阵:

In [1]: import numpy as np

In [2]: a = np.arange(100).reshape((-1,10))

In [3]: a
Out[3]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

您可以选择这样的2x2子矩阵:

In [4]: a[3:5, 0:2]
Out[4]: 
array([[30, 31],
       [40, 41]])

这里的图片是a[row:row+2, column:column+2]。使用上面显示的reshapeargsort技术,您可以创建新值。

In [5]: p = a[3:5, 0:2]

In [6]: e = 4-np.argsort(p.reshape((1,4))).reshape((2,2))

In [7]: e
Out[7]: 
array([[4, 3],
       [2, 1]])

然后,您可以将此结果放在原始数组或副本中:

In [12]: a[3:5, 0:2] = e

In [13]: a
Out[13]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [ 4,  3, 32, 33, 34, 35, 36, 37, 38, 39],
       [ 2,  1, 42, 43, 44, 45, 46, 47, 48, 49],
       [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
       [70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
       [80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

请注意,对于2x2子矩阵,图像的宽度和高度都需要均匀才能正常工作...

答案 1 :(得分:0)

也许这会有所帮助[参考here]

调用:

x = np.arange(36).reshape((6, 6))
print(x)
b = sliding_window(x, (2, 3), None, False) 
print(b)