Python: сжатие / расширение 2D-массивов во фракциях

Есть 2D arrays чисел как выходы некоторых числовых процессов в виде 1x1, 3x3, 5x5, ... в форме, что соответствует разным разрешениям.

На этапе среднее значение, т.е. двумерное значение массива в форме nxn должен быть произведен. Если результаты были в согласованной форме, то есть, скажем, все в 11x11 решение было очевидным, так что:

element_wise_mean_of_all_arrays,

Для задачи этого поста, однако, массивы имеют разные формы, поэтому очевидный способ не работает!

Я думал, что это может быть какая-то помощь с помощью kron функционировать, однако это не так. Например, если массив имеет форму 17x17 как это сделать 21x21, Так что для всех остальных из 1x1, 3x3,..., чтобы построить массив постоянной формы, скажем, 21x21, Также может быть так, что массивы имеют меньшую и большую форму по сравнению с целевой формой. Это массив 31x31 быть втянутым в 21x21,

You could imagine the problem as a very common task for images, being shrunk or extended.

What are possible efficient approaches to do the same jobs on 2D arrays, in Python, using numpy, scipy, etc?

Updates: Here is a bit optimized version of the accepted answer bellow:


def resize(X,shape=None):
    if shape==None:
        return X
    m,n = shape
    Y = np.zeros((m,n),dtype=type(X[0,0]))
    k = len(X)
    p,q = k/m,k/n
    for i in xrange(m):
        Y[i,:] = X[i*p,np.int_(np.arange(n)*q)]
    return Y

It works perfectly, however do you all agree it is the best choice in terms of the efficiency? If not any improvement?


# Expanding ---------------------------------

>>> X = np.array([[1,2,3],[4,5,6],[7,8,9]])
[[1 2 3]
 [4 5 6]
 [7 8 9]]

>>> resize(X,[7,11])
[[1 1 1 1 2 2 2 2 3 3 3]
 [1 1 1 1 2 2 2 2 3 3 3]
 [1 1 1 1 2 2 2 2 3 3 3]
 [4 4 4 4 5 5 5 5 6 6 6]
 [4 4 4 4 5 5 5 5 6 6 6]
 [7 7 7 7 8 8 8 8 9 9 9]
 [7 7 7 7 8 8 8 8 9 9 9]]

# Shrinking ---------------------------------

>>> X = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [13 14 15 16]]

>>> resize(X,(2,2))
[[ 1  3]
 [ 9 11]]

Final note: that the code above easily could be translated to Fortran for the highest performance possible.

1 ответ

Решение

Я не уверен, что я точно понимаю, что вы пытаетесь, но если то, что я думаю, самый простой способ будет:

wanted_size = 21
a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
b = numpy.zeros((wanted_size, wanted_size))

for i in range(wanted_size):
    for j in range(wanted_size):
        idx1 = i * len(a) / wanted_size
        idx2 = j * len(a) / wanted_size
        b[i][j] = a[idx1][idx2]

Вы можете заменить b[i][j] = a[idx1][idx2] какой-нибудь пользовательской функцией, например, средним значением матрицы 3x3 с центром в [idx1] [idx2] или некоторой интерполяционной функцией.

Другие вопросы по тегам