Подтвердить что ты не робот

Массивный массив в Python

У меня есть базовые 2-D массивы numpy, и я бы хотел "уменьшить их" до более грубого разрешения. Есть ли простой модуль numpy или scipy, который может легко сделать это? Следует также отметить, что этот массив отображается географически через модули Basemap.

SAMPLE: enter image description here

4b9b3361

Ответ 1

scikit-image здесь была реализована рабочая версия downsampling, хотя они не могут назвать ее downsampling, поскольку она не является понижающей дискретизацией в терминах DSP, если я правильно понимаю:

http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.block_reduce

но он работает очень хорошо, и это единственный downsampler, который я нашел в Python, который может иметь дело с np.nan в изображении. С этими очень быстрыми темпами сбрасываются огромные изображения.

Ответ 2

При понижающей дискретизации интерполяция - это неправильная вещь. Всегда используйте агрегированный подход.

Я использую блокирующие средства для этого, используя "фактор", чтобы уменьшить разрешение.

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

Например, массив формы (100, 200) с коэффициентом 5 (5 × 5 блоков) приводит к результату массива (20, 40):

ar = np.random.rand(20000).reshape((100, 200))
block_mean(ar, 5).shape  # (20, 40)

Ответ 3

imresize и ndimage.interpolation.zoom выглядят они делают то, что вы хотите

Я еще не пробовал imresize, но вот как я использовал ndimage.interpolation.zoom

a = np.array(64).reshape(8,8)
a = ndimage.interpolation.zoom(a,.5) #decimate resolution

a - это матрица 4x4 с интерполированными значениями в ней

Ответ 4

Поскольку операционному оператору просто нужно разрешение, то я решил поделиться своим способом уменьшения количества пикселей вдвое в каждом измерении. Я взял среднее 2х2 блоков. Это можно применять несколько раз, чтобы уменьшить в 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]

Ответ 5

Возможно, это не то, что вы ищете, но я подумал, что упомянул об этом для полноты.

Вы можете попробовать установить scikits.samplerate (docs), который является оболочкой Python для libsamplerate. Он обеспечивает хорошие высококачественные алгоритмы повторной дискретизации - НО, насколько я могу судить, он работает только в 1D. Возможно, вы сможете выполнить повторный выбор вашего 2D-сигнала сначала по одной оси, а затем по другой, но я думаю, что это может противодействовать преимуществам высококачественной передискретизации для начала.

Ответ 6

Самый простой способ: Вы можете использовать нотацию 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)

имеет вывод:

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]]