我正在寻找一种将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做到这一点?这种类型的重新划分是否有名称(在搜索方法时会有帮助)?
答案 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()
以下是一些具有不同网格的示例:
也可以进行羽绒采样。
完成此操作后,我非常确定我所做的一切都是某种形式的image sampling。如果您希望在大型列表中执行此操作,那么您将需要提高效率,因为它会非常慢。