将2D numpy数组重新采样为任意维度

时间:2014-11-13 15:12:49

标签: python arrays

我正在寻找一种将numpy 2D数组重新调整为任意维度的方法,使得重新调整后的数组中的每个单元格都包含它(部分)覆盖的所有单元格的加权平均值。

如果新尺寸是原始尺寸的倍数,我找到了几种方法。例如,给定一个4x4阵列,可以将其重新缩放为2x2阵列,其中第一个单元格是原始单元格中4个左上角单元格的平均值。但是这些方法似乎都不适用于例如从4x4开始数组为3x3数组。

此图片说明了从4x4(黑色网格)到3x3(红色网格)的情况下我想做的事情: https://www.dropbox.com/s/iutym4frcphcef2/regrid.png?dl=0

较小阵列中的单元格(0,0)覆盖整个单元格(0,0)和部分单元格(1,0),(0,1)和(1,1)。我希望新细胞包含这些细胞的平均值,这些细胞由黄色,绿色,蓝色和橙色区域加权。

有没有办法用numpy / scipy做到这一点?这种类型的重新划分是否有名称(在搜索方法时会有帮助)?

1 个答案:

答案 0 :(得分:0)

你走了:#

它使用Interval包来轻松计算不同网格的单元格的重叠,因此您需要抓住它。

from matplotlib import pyplot
import numpy
from interval import Interval, IntervalSet

def overlap(rect1, rect2):
  """Calculate the overlap between two rectangles"""
  xInterval = Interval(rect1[0][0], rect1[1][0]) & Interval(rect2[0][0], rect2[1][0])
  yInterval = Interval(rect1[0][1], rect1[1][1]) & Interval(rect2[0][1], rect2[1][1])
  area = (xInterval.upper_bound - xInterval.lower_bound) * (yInterval.upper_bound - yInterval.lower_bound)
  return area


def meanInterp(data, m, n):

  newData = numpy.zeros((m,n))
  mOrig, nOrig = data.shape

  hBoundariesOrig, vBoundariesOrig = numpy.linspace(0,1,mOrig+1), numpy.linspace(0,1,nOrig+1)
  hBoundaries, vBoundaries = numpy.linspace(0,1,m+1), numpy.linspace(0,1,n+1)

  for iOrig in range(mOrig):
    for jOrig in range(nOrig):
      for i in range(m):
        if hBoundaries[i+1] <= hBoundariesOrig[iOrig]: continue
        if hBoundaries[i] >= hBoundariesOrig[iOrig+1]: break
        for j in range(n):
          if vBoundaries[j+1] <= vBoundariesOrig[jOrig]: continue
          if vBoundaries[j] >= vBoundariesOrig[jOrig+1]: break

          boxCoords = ((hBoundaries[i], vBoundaries[j]),(hBoundaries[i+1], vBoundaries[j+1]))
          origBoxCoords = ((hBoundariesOrig[iOrig], vBoundariesOrig[jOrig]),(hBoundariesOrig[iOrig+1], vBoundariesOrig[jOrig+1]))

          newData[i][j] += overlap(boxCoords, origBoxCoords) * data[iOrig][jOrig] / (hBoundaries[1] * vBoundaries[1])

  return newData



fig = pyplot.figure()
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)

m1, n1 = 37,59
m2, n2 = 10,13

dataGrid1 = numpy.random.rand(m1, n1)
dataGrid2 = meanInterp(dataGrid1, m2, n2)

mat1 = ax1.matshow(dataGrid1, cmap="YlOrRd")
mat2 = ax2.matshow(dataGrid2, cmap="YlOrRd")

#make both plots square
ax1.set_aspect(float(n1)/float(m1))
ax2.set_aspect(float(n2)/float(m2))



pyplot.show()

以下是一些具有不同网格的示例:

2x2 grid mapped to a 5x5 grid

3x2 grid mapped to 5x7

5x5-59x59

也可以进行羽绒采样。 37x69-10x13

完成此操作后,我非常确定我所做的一切都是某种形式的image sampling。如果您希望在大型列表中执行此操作,那么您将需要提高效率,因为它会非常慢。