<p>我试着缩小一个光栅——取一个大约6000×2000大小的光栅,把它变成一个任意大小的小光栅,在以前的存储箱大小上取平均值。我找到了一个使用SciPy的解决方案,但是我无法让SciPy安装到我正在使用的共享托管服务上,所以我只编写了这个函数。可能有更好的方法可以做到这一点,不需要在行和列之间循环,但这似乎确实有效。</p>
<p>这方面的好处是,旧的行数和列数不必被新的行数和列数整除。</p>
<pre><code>def resize_array(a, new_rows, new_cols):
'''
This function takes an 2D numpy array a and produces a smaller array
of size new_rows, new_cols. new_rows and new_cols must be less than
or equal to the number of rows and columns in a.
'''
rows = len(a)
cols = len(a[0])
yscale = float(rows) / new_rows
xscale = float(cols) / new_cols
# first average across the cols to shorten rows
new_a = np.zeros((rows, new_cols))
for j in range(new_cols):
# get the indices of the original array we are going to average across
the_x_range = (j*xscale, (j+1)*xscale)
firstx = int(the_x_range[0])
lastx = int(the_x_range[1])
# figure out the portion of the first and last index that overlap
# with the new index, and thus the portion of those cells that
# we need to include in our average
x0_scale = 1 - (the_x_range[0]-int(the_x_range[0]))
xEnd_scale = (the_x_range[1]-int(the_x_range[1]))
# scale_line is a 1d array that corresponds to the portion of each old
# index in the_x_range that should be included in the new average
scale_line = np.ones((lastx-firstx+1))
scale_line[0] = x0_scale
scale_line[-1] = xEnd_scale
# Make sure you don't screw up and include an index that is too large
# for the array. This isn't great, as there could be some floating
# point errors that mess up this comparison.
if scale_line[-1] == 0:
scale_line = scale_line[:-1]
lastx = lastx - 1
# Now it's linear algebra time. Take the dot product of a slice of
# the original array and the scale_line
new_a[:,j] = np.dot(a[:,firstx:lastx+1], scale_line)/scale_line.sum()
# Then average across the rows to shorten the cols. Same method as above.
# It is probably possible to simplify this code, as this is more or less
# the same procedure as the block of code above, but transposed.
# Here I'm reusing the variable a. Sorry if that's confusing.
a = np.zeros((new_rows, new_cols))
for i in range(new_rows):
the_y_range = (i*yscale, (i+1)*yscale)
firsty = int(the_y_range[0])
lasty = int(the_y_range[1])
y0_scale = 1 - (the_y_range[0]-int(the_y_range[0]))
yEnd_scale = (the_y_range[1]-int(the_y_range[1]))
scale_line = np.ones((lasty-firsty+1))
scale_line[0] = y0_scale
scale_line[-1] = yEnd_scale
if scale_line[-1] == 0:
scale_line = scale_line[:-1]
lasty = lasty - 1
a[i:,] = np.dot(scale_line, new_a[firsty:lasty+1,])/scale_line.sum()
return a
</code></pre>