python - 如何在没有numpy循环的情况下分配给大矩阵中的方形子矩阵

标签 python numpy vectorization

我如何向量化这个循环,它使用 numpy 数组填充一个较大矩阵的两个方形子矩阵(也保持较大矩阵对称):

for x in range(n):
    assert m[x].shape == (n,)
    M[i:i+n,j+x] = m[x]
    M[j+x,i:i+n] = m[x]

这很诱人,但不同意上面的循环(参见下面的示例分歧):

assert m.shape == (n,n)
M[i:i+n,j:j+n] = m
M[j:j+n,i:i+n] = m

这是一个小例子(n>1 时崩溃):

from numpy import arange,empty,NAN
from numpy.testing import assert_almost_equal

for n in (1,2,3,4):
    # make the submatrix
    m = (10 * arange(1, 1 + n * n)).reshape(n, n)

    N = n # example below, submatrix is the whole thing

    # M1 using loops, M2 "vectorized"
    M1 = empty((N, N))
    M2 = empty((N, N))
    M1.fill(NAN)
    M2.fill(NAN)

    i,j = 0,0 # not really used when (n == N)

    # this results in symmetric matrix
    for x in range(n):
        assert m[x].shape == (n,)
        M1[i:i+n,j+x] = m[x]
        M1[j+x,i:i+n] = m[x]

    # this does not work as expected
    M2[i:i+n,j:j+n] = m
    M2[j:j+n,i:i+n] = m

    assert_almost_equal(M1,M1.transpose(),err_msg="M not symmetric?")
    print "M1\n",M1,"\nM2",M2
    assert_almost_equal(M1,M2,err_msg="M1 (loop) disagrees with M2 (vectorized)")

我们最终得到:

M1 = [10 30
      30 40] # symmetric

M2 = [10 20
      30 40] # i.e. m

最佳答案

您的测试不正确: 对于 i,j=0,0,您的 M2[]= 赋值只是覆盖相同的矩阵 block 。

使用 M1 时得到对称矩阵的原因是因为你赋值 单个循环中的 M1 值。

如果你将循环分成两部分:

for x in range(n):
      M1[i:i+n,j+x] = m[x]
for x in range(n): 
      M1[j+x,i:i+n] = m[x]

M1 显然与 M2 相同。

总而言之,以下代码有效(相当于您的 M2 计算)但是!只有在对角线上方和下方的 block 之间没有重叠时,它才会起作用。如果有,你必须决定在那里做什么

xs=np.arange(4).reshape(2,2)
ys=np.zeros((7,7))
ys[i:i+n,j:j+n]=xs
ys[j:j+n,i:i+n]=xs.T
print ys
>> array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  2.,  3.,  0.,  0.],
       [ 0.,  0.,  2.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  3.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]])

关于python - 如何在没有numpy循环的情况下分配给大矩阵中的方形子矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10989102/

相关文章:

python - 在 Dataframe float32 列上使用 list(zip(...)) 时出现 float 问题

python - 将 python websocket 客户端与 tkinter 结合使用

python - 在python中组合两个字符串

python - Pandas 矢量化 - 在另一个 DataFrame 中查找最近的 future 时间

python - 从 pandas 数据框列表中选择数据框列

python - 使用索引数组中的索引元组索引多维数组 - NumPy/Python

python - ValueError : `class_weight` must contain all classes in the data. 类{1,2,3}存在于数据中但不存在于 `class_weight`

python - 使用 Numpy Convolve 时幅度发生变化

python - Genfromtxt 抛出异常 "got 3 columns instead of 27"但事实并非如此

python - 使用 numpy 广播减去二维数组