将操作应用于矩阵的行,但某些行除外

时间:2014-05-18 20:12:17

标签: python numpy

我有一个numpy矩阵M,我需要对矩阵的所有行应用一些操作,但确定的行除外。

例如,假设我有行[3,5],其元素应该从M[:,8] = 4之类的操作中避免。所以我希望将第8列的所有行设置为4,但我想避免对第3行和第5行执行此操作。如何在numpy中执行此操作?

编辑:基本上我需要这样做以避免在通过行的元素之和进行归一化时除以零。有些行都是零,所以进行求和(为零)然后除以求和将得到除以零。我正在做的是我发现哪些行都是零,然后我不想对那些特定的行进行规范化操作。

2 个答案:

答案 0 :(得分:1)

也许是这样的?

>>> import numpy as np
>>> M = np.arange(32).reshape(8, 4)
>>> ignore = {3, 5}
>>> rest = [i for i in xrange(M.shape[0]) if i not in ignore]
>>> M[rest, 3] = 4
>>> M
array([[ 0,  1,  2,  4],
       [ 4,  5,  6,  4],
       [ 8,  9, 10,  4],
       [12, 13, 14, 15],
       [16, 17, 18,  4],
       [20, 21, 22, 23],
       [24, 25, 26,  4],
       [28, 29, 30,  4]])

答案 1 :(得分:0)

根据您的修改,为了解决您的具体问题,您似乎在操作带有非负条目的矩阵,您可以利用以下技巧

import numpy as np
rng = np.random.RandomState(42)
M = rng.randn(10, 10) ** 2
M[[0, 5]] = 0.  # set 2 lines to 0

M_norm = M / (M.sum(axis=1) + 1e-18)[:, np.newaxis]

显然这个结果不准确,但确切到不足以发现差异。为了使它稍微好一点,你也可以写

M_norm = M / np.maximum(M.sum(axis=1), 1e-18)[:, np.newaxis]

如果这仍然不够,并且你想要它是准确的,对于一般情况(允许否定性)你可以写

row_sums = M.sum(axis=1)
row_sums[row_sums == 0] = 1.

M_norm = M / row_sums[:, np.newaxis]  # dividing the zeros by 1 still yields 0

要添加一些健壮性,您也可以

tolerance = 1e-6

row_sums = M.sum(axis=1)
OK_rows = np.abs(row_sums) > tolerance
M_norm = np.zeros_like(M)
M_norm[OK_rows] = M[OK_rows] / row_sums[OK_rows][:, np.newaxis]