这是一种使用矩阵乘法来完成您所要求的操作的方法,它不需要新的数组维度来除旧。
首先,我们生成一个行压缩矩阵和一个列压缩矩阵(我确信有一种更简洁的方法可以做到这一点,甚至可以单独使用 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]]