Python: сжатие / расширение 2D-массивов в дробных единицах - PullRequest
3 голосов
/ 24 января 2012

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

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

element_wise_mean_of_all_arrays.

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

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

Вы можете представить себе проблему как очень распространенную задачу для изображений, сжатых или расширенных.

ЧтоВозможны ли эффективные подходы для выполнения тех же задач на массивах 2D, в Python, с использованием numpy, scipy и т. д.?

Обновления: Вот немного оптимизированная версияПринятый ответ ниже:


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

Он отлично работает, однако вы все согласны с тем, что лучший выбор с точки зрения эффективности?Если нет каких-либо улучшений?


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

Заключительное примечание: , что приведенный выше код легко может быть переведен в Fortran для максимально возможной производительности.

1 Ответ

3 голосов
/ 24 января 2012

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

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] или некоторой функцией интерполяции.

...