将2D numpy数组重采样到任意维

2024-10-02 14:25:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来重新缩放一个numpy2d数组到任意维,这样重缩放数组中的每个单元都包含它(部分)覆盖的所有单元的加权平均值。在

如果新维度是原始维度的倍数,我已经找到了几种方法来实现这一点。例如,给定一个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做到这一点?有没有这种重新划分的名称(在搜索方法时会有帮助)?在


Tags: 方法httpscom网格www情况数组dropbox
1条回答
网友
1楼 · 发布于 2024-10-02 14:25:12

给你:

它使用^{}包来轻松地计算不同网格单元的重叠,因此您需要获取它。在

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。如果你想在大名单上做这件事,那么你就需要让事情变得更有效率,因为这会很慢。在

相关问题 更多 >