首页 > 解决方案 > Python:将for循环操作扩展到矩阵中的每一行而不使用迭代

问题描述

我有一段这样的代码:

a = Y[0]; b = Z[0]
print(a, b)
loss = 0
for i in range(len(a)):
    k = len(a)-i
    loss += (2**(k-1))*np.abs(a[i]-b[i])
print(loss)

whereYZare 的维度250 x 10,每行是 10 位二进制值。例如,print(a,b)打印这个:[1 0 0 0 0 0 0 0 1 0] [0 0 0 1 1 1 1 1 0 0]

Y现在我想在 for 循环中为和之间的对应行应用两行函数Z。但我不想做这样的事情:

for j in range(Y.shape[0]):
    a = Y[j]; b = Z[j]
    loss = 0
    for i in range(len(a)):
        k = len(a)-i
        loss += (2**(k-1))*np.abs(a[i]-b[i])
    print(loss)

我本质上是在尝试在 keras/tensorflow 中创建自定义损失函数。并且那个 for 循环示例不适用于大型张量操作。如何使用某种批处理矩阵运算而不是 for 循环来做到这一点?

标签: pythontensorflow

解决方案


如果只需要对内部循环进行 numpy 并行化:

import numpy as np

for j in range(Y.shape[0]):
    a = Y[j]; b = Z[j]
    loss = 0
    """
    for i in range(len(a)):
        k = len(a)-i
        loss += (2**(k-1))*np.abs(a[i]-b[i])
    """
    k = np.arange(len(a), 0, -1)
    loss = np.sum(np.multiply(2**(k-1), np.abs(a-b)))
    print(loss)

编辑

要使其更加 numpy 并行化,请使用以下方法:

import numpy as np

# This function computes loss for row pairs
def get_loss(row, sz):
    loss = 0
    k = np.arange(sz, 0, -1)
    loss = np.sum(np.multiply(2**(k-1), np.abs(row[:sz]-row[sz:])))
    return loss

# Sample input matrices
A = np.random.random((5, 10))
B = np.random.random((5, 10))

# Concatenate the input matrices
AB = np.concatenate((A, B), axis=1)

# apply the function on each row pair
result = np.apply_along_axis(get_loss, 1, AB, A.shape[1])

# result is a 1D array of the losses
print(result.shape)

推荐阅读