将数组复制到NumPy中另一个数组的一部分

时间:2018-10-08 12:54:10

标签: python-3.x numpy numpy-broadcasting

我想将较小的数组A复制到较大的数组B中,如下所示: copy array into part of another array 这样做的显而易见的方法是计算A的哪一部分适合B,然后仅将该部分复制到目标数组B的预先计算的部分。这是一个繁琐且容易出错的任务,尤其是在更高维度中。有没有一种简便的方法(即无需计算所有索引)来实现这一目标?

一个澄清的词-通常必须:

在X轴上的

:计算A的多少元素适合B的部分,从A的大小中减去该元素,重新计算B适合的起点和终点(索引),重新计算A的索引。在第二维度重复(可能更多) )。插入looong切片公式,该公式绝对不可读,然后确保在此过程中不会遗漏任何内容。这就是我所说的乏味且容易出错的。可以做到,但是有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以利用NumPy数组算法来处理N个维度,与处理1个维度一样。此外,可以计算N维的切片 调用map(slice, start_indices, end_indices),并生成这些切片后,实际的复制就变成了单行:B[B_slices] = A[A_slices]

import numpy as np

def copy_from(A, B, A_start, B_start, B_end):
    """
    A_start is the index with respect to A of the upper left corner of the overlap
    B_start is the index with respect to B of the upper left corner of the overlap
    B_end is the index of with respect to B of the lower right corner of the overlap
    """
    A_start, B_start, B_end = map(np.asarray, [A_start, B_start, B_end])
    shape = B_end - B_start
    B_slices = tuple(map(slice, B_start, B_end + 1))
    A_slices = tuple(map(slice, A_start, A_start + shape + 1))
    B[B_slices] = A[A_slices]

A = np.zeros((21,15))
B = np.ones((16,15))
A_start = [11, 5]
B_start =  [6, 0]
B_end =  [15, 9]
copy_from(A, B, A_start, B_start, B_end)
print(B)

收益

[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]]