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