计算矩阵中两行所有组合的点积

时间:2019-07-09 17:05:14

标签: python jupyter-notebook

我是编程新手,我正在尝试计算N * 3矩阵中任何拖曳行的所有组合的点积。

例如对于N = 5,我有矩阵

   [0.64363829, 0.21027068, 0.7358777 ],
   [0.39138384, 0.49072791, 0.7784631 ],
   [0.22952251, 0.90537974, 0.35722115],
   [0.40108871, 0.88992243, 0.21717715],
   [0.06710475, 0.84022499, 0.53806962]

并且我想计算以下行的所有组合的点积:row1 * row2,row1 * row3,row1 * row4,row1 * row5,row2 * row3 ... row4 * row5。

我不确定如何解决此问题,因此我尝试了一些方法。到目前为止,我有

for i in range(N-1): 
    for l in range(1, N): 
        dotms = (np.dot(nmag[(i),:], nmag[(i+l),:]))
        print(dotms)

其中nmag是5 * 3矩阵

输出只有7个答案,但是有5行我正在寻找10个不同的组合

[0.92794896、0.60097537、0.60509647、0.6158193、0.81220999,        0.76275382,0.85745291]

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

您的循环索引不太适合您的任务:

import numpy as np
nmag = np.array([[0.64363829, 0.21027068, 0.7358777 ],
                 [0.39138384, 0.49072791, 0.7784631 ],
                 [0.22952251, 0.90537974, 0.35722115], 
                 [0.40108871, 0.88992243, 0.21717715],
                 [0.06710475, 0.84022499, 0.53806962]])

for i in range(N-1):  # iterate over all rows but the last
    for j in range(i+1, N):   # start j from i+1 
        dotms = np.dot(nmag[i, :], nmag[j, :])
        print(dotms)

答案 1 :(得分:1)

我不知道我是否误会了你的意思,但是nmag.dot(nmag.T)会得到你想要的吗?

In [5]: nmag.dot(nmag.T)
Out[5]:
array([[1.        , 0.92794895, 0.60097537, 0.60509647, 0.6158193 ],
       [0.92794895, 0.99999999, 0.81220999, 0.76275381, 0.85745291],
       [0.60097537, 0.81220999, 1.00000001, 0.9753569 , 0.96833458],
       [0.60509647, 0.76275381, 0.9753569 , 1.        , 0.89150645],
       [0.6158193 , 0.85745291, 0.96833458, 0.89150645, 1.        ]])

,如果您只是想获取不同行的点积。

In [17]: res = nmag.dot(nmag.T)

In [18]: [res[i, j] for i in range(res.shape[0]) for j in range(res.shape[1]) if i<j]
Out[18]:
[0.9279489524047824,
 0.6009753676942861,
 0.6050964675806133,
 0.6158193009466447,
 0.8122099927113468,
 0.7627538110746328,
 0.8574529124107328,
 0.9753568970221529,
 0.9683345820770881,
 0.8915064490330812]

答案 2 :(得分:0)

为了在 Woods Chen 出色的 answer 上反弹,还可以使用 np.triu()np.tril() 以及它们各自的函数来为给定的三角形矩阵形状构建索引:{{ 3}} 或 np.triu_indices()。如果我们只想提取非冗余部分,这很有用(因为这种点积矩阵根据定义是对称的)。

这里是一个使用点积矩阵的上三角部分的例子:

import numpy as np

mat = np.array([[0.64363829, 0.21027068, 0.7358777 ],
                [0.39138384, 0.49072791, 0.7784631 ],
                [0.22952251, 0.90537974, 0.35722115], 
                [0.40108871, 0.88992243, 0.21717715],
                [0.06710475, 0.84022499, 0.53806962]])

dp = mat.dot(mat.T) # dp := dot_product matrix

dp_unique_vector_indices = np.triu_indices(mat.shape[0]) # assume square matrix
dp_unique_vector_indices_without_diagonal = np.triu_indices(mat.shape[0], 1) # skip the diagonal of ones here

dp_unique_vector = np.triu(dp)[dp_unique_vector_indices]
dp_unique_vector_without_diagonal = np.triu(dp)[dp_unique_vector_indices_without_diagonal]

dp_unique_vector 如下:

array([1.       , 0.927949 , 0.6009754, 0.6050965, 0.6158193, 1.       ,
       0.81221  , 0.7627538, 0.8574529, 1.       , 0.9753569, 0.9683346,
       1.       , 0.8915064, 1.       ])

dp_unique_vector_without_diagonal 是:

array([0.927949 , 0.6009754, 0.6050965, 0.6158193, 0.81221  , 0.7627538,
       0.8574529, 0.9753569, 0.9683346, 0.8915064])

与全点积矩阵相比:

array([[1.       , 0.927949 , 0.6009754, 0.6050965, 0.6158193],
       [0.927949 , 1.       , 0.81221  , 0.7627538, 0.8574529],
       [0.6009754, 0.81221  , 1.       , 0.9753569, 0.9683346],
       [0.6050965, 0.7627538, 0.9753569, 1.       , 0.8915064],
       [0.6158193, 0.8574529, 0.9683346, 0.8915064, 1.       ]])