79651148

Date: 2025-06-03 11:35:35
Score: 0.5
Natty:
Report link

I had spent manytime, trying to find a better method for downsampling arrays. Let's suppose, I have an array of points, or pixels, having an initial size. And I want to downsample it, to a final size count, and a reduction factor ks. The first thing, that I tried, was the numpy slicing, using a step equal to ks.

count = size // ks
points = np.empty(dtype=np.float32, shape=(count * ks, )) 
## Initialize the points array as necessary... 
res = points[::ks] 

But if the result array, already has a fixed shape, this could get an error. So the array must be resized, don't use reshape, because this also gets error.

res = np.empty(dtype=np.float32, shape=(count, )) 
res[:] = np.resize(points[::ks], (count, )) 

This is quite a simple method, and seems to be pretty fast for bigger arays. The problem with this resize, is that, it can fill the array with NaN values.

Another method would be also, to make an interpollation over the numpy array. As far I had tried, the zoom method from the scipy package would be suitable.

from scipy import ndimage
fact = (1/ks, 1.00)
res[:] = np.resize(ndimage.zoom(points, zoom=fact, order=1), (count, ))

It can be noticed, that I didn't use a simple scalar factor ks, but a tuple. Using a simple scalar factor, an image will result compressed, or stretched. But with proper scaling factors on different axes, it preserves its' aspect. It also depends, of the arrays' shape, which may differ from case to case. The order parameter sets an interpolation method being used at subsampling.

Note, that I also used the resize method, to avoid other dimensional errors. It is enough just a difference of 1 in the count size, to get another error. The shape of an array, can't be simply set, by changing the size property. Or the array must be a numpy.ndarray, in order to access the size property.

#res.shape = (sx//fact, sy//fact)
res = np.resize(res, (sx//fact, sy//fact)) 

As other people said, can be a problem with interpolation over array blocks. This is because, different parts of the image, could be mixed in an average. I had even tried, to roll, or shift the array, with just some smaller steps. But when shifting an array, the last values are filled before the first ones. And if the values was previously sorted, these would not come in right order. The resulting image may look, as an overlapping of some irregular rectangles. The idea was also, to use a numpy mean, over 1, or more sorted array blocks.

Reasons:
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Adrian