Вот отличный код @ jorgeca как функция, с некоторыми тестами - я расширил фрагменты, чтобы сделать его немного более читабельным:
import numpy as np
def addAtPos(matrix1, matrix2, xypos, inPlace=False):
"""
Add matrix2 into matrix1 at position xypos (x,y), in-place or in new matrix.
Handles matrix2 going off edges of matrix1.
"""
x, y = xypos
h1, w1 = matrix1.shape
h2, w2 = matrix2.shape
# get slice ranges for matrix1
x1min = max(0, x)
y1min = max(0, y)
x1max = max(min(x + w2, w1), 0)
y1max = max(min(y + h2, h1), 0)
# get slice ranges for matrix2
x2min = max(0, -x)
y2min = max(0, -y)
x2max = min(-x + w1, w2)
y2max = min(-y + h1, h2)
if inPlace:
# add matrix2 into matrix1, in place
matrix1[y1min:y1max, x1min:x1max] += matrix2[y2min:y2max, x2min:x2max]
else:
# create and return a new matrix
matrix1copy = matrix1.copy()
matrix1copy[y1min:y1max, x1min:x1max] += matrix2[y2min:y2max, x2min:x2max]
return matrix1copy
def test_addAtPos():
matrix1 = np.zeros((2,2))
matrix2 = np.ones((2,2))
test(addAtPos(matrix1, matrix2, ( 0, 0)), [[1,1],[1,1]])
test(addAtPos(matrix1, matrix2, ( 2, 2)), [[0,0],[0,0]])
test(addAtPos(matrix1, matrix2, (-1,-1)), [[1,0],[0,0]])
test(addAtPos(matrix1, matrix2, ( 1,-1)), [[0,1],[0,0]])
test(addAtPos(matrix1, matrix2, ( 1, 1)), [[0,0],[0,1]])
test(addAtPos(matrix1, matrix2, (-1, 1)), [[0,0],[1,0]])
def test(actual, expected, message=''):
"Compare actual and expected values and print OK or FAIL"
passed = (actual == expected)
if type(passed) == np.ndarray:
passed = passed.all()
actual = str(actual).replace('\n', '')
expected = str(expected).replace('\n', '')
if passed:
print('[OK] ', message, actual)
else:
print('[FAIL]', message, actual, ' != expected value of', expected)
test_addAtPos()
Вывод:
[OK] [[1. 1.] [1. 1.]]
[OK] [[0. 0.] [0. 0.]]
[OK] [[1. 0.] [0. 0.]]
[OK] [[0. 1.] [0. 0.]]
[OK] [[0. 0.] [0. 1.]]
[OK] [[0. 0.] [1. 0.]]