Python中的下采样数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18666014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Downsample array in Python
提问by wuffwuff
I have basic 2-D numpy arrays and I'd like to "downsample" them to a more coarse resolution. Is there a simple numpy or scipy module that can easily do this? I should also note that this array is being displayed geographically via Basemap modules.
我有基本的二维 numpy 数组,我想将它们“下采样”到更粗糙的分辨率。是否有一个简单的 numpy 或 scipy 模块可以轻松做到这一点?我还应该注意到,这个数组是通过 Basemap 模块在地理上显示的。
SAMPLE:
样本:
回答by Hammer
imresizeand ndimage.interpolation.zoomlook like they do what you want
imresize和ndimage.interpolation.zoom看起来他们做你想做的
I haven't tried imresize before but here is how I have used ndimage.interpolation.zoom
我之前没有尝试过 imresize 但这里是我如何使用 ndimage.interpolation.zoom
a = np.array(64).reshape(8,8)
a = ndimage.interpolation.zoom(a,.5) #decimate resolution
a is then a 4x4 matrix with interpolated values in it
a 是一个 4x4 矩阵,其中包含内插值
回答by lmjohns3
This might not be what you're looking for, but I thought I'd mention it for completeness.
这可能不是你要找的,但我想我会提到它的完整性。
You could try installing scikits.samplerate
(docs), which is a Python wrapper for libsamplerate. It provides nice, high-quality resampling algorithms -- BUT as far as I can tell, it only works in 1D. You might be able to resample your 2D signal first along one axis and then along another, but I'd think that might counteract the benefits of high-quality resampling to begin with.
您可以尝试安装scikits.samplerate
( docs),它是 libsamplerate 的 Python 包装器。它提供了很好的、高质量的重采样算法——但据我所知,它只适用于 1D。您可以先沿着一个轴然后沿着另一个轴重新采样 2D 信号,但我认为这可能会抵消高质量重新采样的好处。
回答by Mike T
When downsampling, interpolation is the wrong thing to do. Always use an aggregated approach.
下采样时,插值是错误的做法。始终使用聚合方法。
I use block means to do this, using a "factor" to reduce the resolution.
我使用块方法来做到这一点,使用“因子”来降低分辨率。
import numpy as np
from scipy import ndimage
def block_mean(ar, fact):
assert isinstance(fact, int), type(fact)
sx, sy = ar.shape
X, Y = np.ogrid[0:sx, 0:sy]
regions = sy/fact * (X/fact) + Y/fact
res = ndimage.mean(ar, labels=regions, index=np.arange(regions.max() + 1))
res.shape = (sx/fact, sy/fact)
return res
E.g., a (100, 200) shape array using a factor of 5 (5x5 blocks) results in a (20, 40) array result:
例如,使用因子 5(5x5 块)的 (100, 200) 形状数组导致 (20, 40) 数组结果:
ar = np.random.rand(20000).reshape((100, 200))
block_mean(ar, 5).shape # (20, 40)
回答by K.-Michael Aye
scikit-image
has implemented a working version of downsampling
here, although they shy away from calling it downsampling
for it not being a downsampling in terms of DSP, if I understand correctly:
scikit-image
已经实现了downsampling
here的一个工作版本,尽管downsampling
如果我理解正确的话,他们不会因为它不是DSP方面的下采样而避免调用它:
http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce
http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce
but it works very well, and it is the only downsampler
that I found in Python that can deal with np.nan
in the image. I have downsampled gigantic images with this very quickly.
但是效果很好,而且是downsampler
我在Python中发现的唯一可以处理np.nan
图像的。我已经非常快速地对巨大的图像进行了下采样。
回答by Josh Albert
Because the OP just wants a courser resolution, I thought I would share my way for reducing number of pixels by half in each dimension. I takes the mean of 2x2 blocks. This can be applied multiple times to reduce by factors of 2.
因为 OP 只想要一个更清晰的分辨率,我想我会分享我将每个维度的像素数减少一半的方法。我取 2x2 块的平均值。这可以应用多次以减少 2 倍。
from scipy.ndimage import convolve
array_downsampled = convolve(array,
np.array([[0.25,0.25],[0.25,0.25]]))[:array.shape[0]:2,:array.shape[1]:2]
回答by Kolibril
Easiest way:
You can use the array[0::2]
notation, which only considers every second index.
E.g.
最简单的方法:您可以使用array[0::2]
表示法,它只考虑每隔一个索引。例如
array= np.array([[i+j for i in range(0,10)] for j in range(0,10)])
down_sampled=array[0::2,0::2]
print("array \n", array)
print("array2 \n",down_sampled)
has the output:
有输出:
array
[[ 0 1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10]
[ 2 3 4 5 6 7 8 9 10 11]
[ 3 4 5 6 7 8 9 10 11 12]
[ 4 5 6 7 8 9 10 11 12 13]
[ 5 6 7 8 9 10 11 12 13 14]
[ 6 7 8 9 10 11 12 13 14 15]
[ 7 8 9 10 11 12 13 14 15 16]
[ 8 9 10 11 12 13 14 15 16 17]
[ 9 10 11 12 13 14 15 16 17 18]]
array2
[[ 0 2 4 6 8]
[ 2 4 6 8 10]
[ 4 6 8 10 12]
[ 6 8 10 12 14]
[ 8 10 12 14 16]]
回答by Q2Learn
This will take an image of any resolution and return only a quarter of its size by taking the 4th index of the image array.
这将获取任何分辨率的图像,并通过获取图像数组的第 4 个索引仅返回其大小的四分之一。
import cv2
import numpy as np
def quarter_res_drop(im):
resized_image = im[0::4, 0::4]
cv2.imwrite('resize_result_image.png', resized_image)
return resized_image
im = cv2.imread('Your_test_image.png', 1)
quarter_res_drop(im)
回答by blaylockbk
xarray's "coarsen" method can downsample a xarray.Dataset or xarray.DataArray
xarray 的 "coarsen" 方法可以对 xarray.Dataset 或 xarray.DataArray 进行下采样
- http://xarray.pydata.org/en/stable/generated/xarray.DataArray.coarsen.html
- http://xarray.pydata.org/en/stable/computation.html#coarsen-large-arrays
- http://xarray.pydata.org/en/stable/generated/xarray.DataArray.coarsen.html
- http://xarray.pydata.org/en/stable/computation.html#coarsen-large-arrays
For example:
例如:
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15,5))
# Create a 10x10 array of random numbers
a = xr.DataArray(np.random.rand(10,10)*100, dims=['x', 'y'])
# "Downscale" the array, mean of blocks of size (2x2)
b = a.coarsen(x=2, y=2).mean()
# "Downscale" the array, mean of blocks of size (5x5)
c = a.coarsen(x=5, y=5).mean()
# Plot and cosmetics
a.plot(ax=ax1)
ax1.set_title("Full Data")
b.plot(ax=ax2)
ax2.set_title("mean of (2x2) boxes")
c.plot(ax=ax3)
ax3.set_title("mean of (5x5) boxes")