これは、古い配列の次元を分割するために新しい配列の次元を必要としない行列乗算を使用して、あなたが求めていることを行う方法です。
まず、行圧縮行列と列圧縮行列を生成します (numpy 操作だけを使用しても、これを行うためのよりクリーンな方法があると確信しています)。
def get_row_compressor(old_dimension, new_dimension):
dim_compressor = np.zeros((new_dimension, old_dimension))
bin_size = float(old_dimension) / new_dimension
next_bin_break = bin_size
which_row = 0
which_column = 0
while which_row < dim_compressor.shape[0] and which_column < dim_compressor.shape[1]:
if round(next_bin_break - which_column, 10) >= 1:
dim_compressor[which_row, which_column] = 1
which_column += 1
elif next_bin_break == which_column:
which_row += 1
next_bin_break += bin_size
else:
partial_credit = next_bin_break - which_column
dim_compressor[which_row, which_column] = partial_credit
which_row += 1
dim_compressor[which_row, which_column] = 1 - partial_credit
which_column += 1
next_bin_break += bin_size
dim_compressor /= bin_size
return dim_compressor
def get_column_compressor(old_dimension, new_dimension):
return get_row_compressor(old_dimension, new_dimension).transpose()
...たとえば、次のようになりget_row_compressor(5, 3)
ます。
[[ 0.6 0.4 0. 0. 0. ]
[ 0. 0.2 0.6 0.2 0. ]
[ 0. 0. 0. 0.4 0.6]]
そしてあなたにget_column_compressor(3, 2)
与えます:
[[ 0.66666667 0. ]
[ 0.33333333 0.33333333]
[ 0. 0.66666667]]
次に、単純に行コンプレッサを事前に乗算し、列コンプレッサを事後乗算して、圧縮された行列を取得します。
def compress_and_average(array, new_shape):
# Note: new shape should be smaller in both dimensions than old shape
return np.mat(get_row_compressor(array.shape[0], new_shape[0])) * \
np.mat(array) * \
np.mat(get_column_compressor(array.shape[1], new_shape[1]))
このテクニックを使って、
compress_and_average(np.array([[50, 7, 2, 0, 1],
[0, 0, 2, 8, 4],
[4, 1, 1, 0, 0]]), (2, 3))
収量:
[[ 21.86666667 2.66666667 2.26666667]
[ 1.86666667 1.46666667 1.86666667]]