Resample 2d Numpy Array To Arbitrary Dimensions
I am looking for a way to rescale a numpy 2D array to arbitrary dimensions in such a way that each cell in the rescaled array contains a weighted mean of all the cells that it (par
Solution 1:
Here you go:#
It uses the Interval
package to easily calculate the overlaps of the cells of the different grids, so you'll need to grab that.
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()
Here are a couple of examples with differing grids:
Down sampling is possible too.
After having done this, i'm pretty sure all i've done is some form of image sampling. If you're looking to do this on large lists, then you're going to need to make things a bit more efficient, as it will be pretty slow.
Post a Comment for "Resample 2d Numpy Array To Arbitrary Dimensions"