我如何向量化两个numpy数组的交互

ddrv8njm  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(98)

考虑两个numpy数组:
1.数组a:数组a的重要特性是每对列(pq)都有一行按该顺序保存值(qp)。
例如,列0和3在行2中保存值3和0,列4和5在行1中保存值5和4。

a = np.array([[1, 0, 4, 5, 2, 3],
              [2, 3, 0, 1, 5, 4],
              [3, 4, 5, 0, 1, 2],
              [4, 5, 3, 2, 0, 1],
              [5, 2, 1, 4, 3, 0]])

字符串
1.数组b:前两列显示数组a中的所有列对(pq)。其余两列是乘数,如下所示:考虑数组b的第5行[1, 2, 4, -3]。我们检查数组a的第1列和第2列,并找到值2和1。然后,我们在数组a中将2替换为2x 4 =8,将1替换为1x(-3)=-3。

b = np.array([[0, 1,  3  -1],
              [0, 2, -1,  3],
              [0, 3, -2,  4],
              [0, 4, -1,  0],
              [0, 5, -1,  4],
              [1, 2,  4, -3],
              [1, 3,  0, -1],
              [1, 4,  1, -2],
              [1, 5,  1,  1],
              [2, 3,  1,  1],
              [2, 4, -1,  0], 
              [2, 5, -1,  1],
              [3, 4,  0,  0],
              [3, 5,  2,  1],
              [4, 5,  1, -2]])


最终结果如下所示:

c = np.array([[ 3, 0,-4,10, 0, 3],
                 [-2, 0, 0,-1, 5,-8],
                 [-6, 4,-5, 0,-2, 2],
                 [-4, 5, 3, 2, 0, 1],
                 [-5, 8,-3, 0, 0, 0]])


这是我一直在使用的。它可以很好地处理较小的数组(生成上面所示的数组c),但我的编码技能相当生疏:

c = np.copy(a)

for brow in b:       
    arow = np.where(a[:, brow[0]] == brow[1])
    c[arow, brow[0]] = (a[arow, brow[0]])*brow[2]
    c[arow, brow[1]] = (a[arow, brow[1]])*brow[3]  
    
print(c)


这个可以矢量化吗?

fv2wmkja

fv2wmkja1#

这是一个需要维度Ascension的解决方案。让我们在一个函数中定义您的代码,用于比较性能。

def find_c(a, b):
    c = np.copy(a)
    for brow in b:       
        arow = np.where(a[:, brow[0]] == brow[1])
        c[arow, brow[0]] = (a[arow, brow[0]])*brow[2]
        c[arow, brow[1]] = (a[arow, brow[1]])*brow[3] 
    return c

字符串
我写了一些评论来解释我的解决方案:

def find_c_1(a, b):
    c = np.copy(a)
    # ascension for indexing the data
    array_find = a[:, None][:, 0, b[:, 0]].T
    # find the index corresponds the values of b[:, 1] in array
    index = np.where(array_find == b[:, 1].reshape(-1, 1))
    
    # index[1] is the index of rows , b[:, 0] is the index of columns 
    # Then the assignment of the values
    c[index[1], b[:, 0]] = c[index[1], b[:, 0]] * b[:, 2]
    c[index[1], b[:, 1]] = c[index[1], b[:, 1]] * b[:, 3]
    return c


比较结果:

c1 = find_c(a, b)
c2 = find_c_1(a, b)
print(np.array_equal(c1, c2))  # True


性能比较:

%timeit find_c(a, b)
314 µs ± 5.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit find_c_1(a, b)
23.8 µs ± 1.06 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

相关问题