Следующее должно хорошо обрабатывать дубликаты.
def mix(a, b, i):
sa, sb = map(np.lexsort, (a.T, b.T))
mb = np.empty(len(a), '?')
mb[sb] = np.arange(2, dtype='?').repeat((i, len(a)-i))[sa]
return np.concatenate([a[:i], b[mb]], 0)
Это
- косвенно сортирует
a
, а b
- создает маску, которая является Истинойв позициях, не взятых из
a
, то есть имеет i
False и затем len(a)-i
Trues. - использует порядки сортировки для сопоставления этой маски с
b
- filters
b
с маской и добавляет к a[:i]
Пример (транспонирован для экономии места):
a.T
# array([[2, 2, 0, 2, 3, 0, 2, 0, 0, 1],
# [0, 1, 2, 0, 1, 0, 3, 0, 0, 0]])
b.T
# array([[0, 0, 2, 1, 0, 0, 2, 2, 2, 3],
# [0, 0, 0, 0, 2, 0, 1, 3, 0, 1]])
mix(a, b, 6).T
# array([[2, 2, 0, 2, 3, 0, 0, 1, 0, 2],
# [0, 1, 2, 0, 1, 0, 0, 0, 0, 3]])