当前位置: 首页 > 知识库问答 >
问题:

计算西皮csr矩阵中的欧氏距离

姚雅珺
2023-03-14

我需要计算存储在csr稀疏矩阵和一些点列表中的所有点之间的欧氏距离。对我来说,将csr转换为稠密的csr会更容易,但由于内存不足,我无法将其转换为稠密的csr,因此我需要将其保留为csr。

例如,我有一个数据\u csr稀疏矩阵(csr和稠密视图):

data_csr
(0, 2)  4
(1, 0)  1
(1, 4)  2
(2, 0)  2
(2, 3)  1
(3, 5)  1
(4, 0)  4
(4, 2)  3
(4, 3)  2

data_csr.todense()
[[0, 0, 4, 0, 0, 0]
 [1, 0, 0, 0, 2, 0]
 [2, 0, 0, 1, 0, 0]
 [0, 0, 0, 0, 0, 1]
 [4, 0, 3, 2, 0, 0]]

这个中心点列表:

center
array([[0, 1, 2, 2, 4, 1],
      [3, 4, 1, 2, 4, 0]])

使用scipy.spatial包,data_csr中心之间的欧几里德距离数组将像下面这样。因此,在center的每行中,总共6个点中的每一个点都是根据data_csr中的所有行计算的。结果数组(2,5)的第一行是center的第一行和data_csr中的所有行之间的ED。

scipy.spatial.distance.cdist(center, data_csr, 'euclidean')

array([[ 5.09901951,  3.87298335,  5.19615242,  5.        ,  5.91607978],
      [ 7.34846923,  5.38516481,  5.91607978,  6.8556546 ,  6.08276253]])


到目前为止,我所学到的是,我可以通过以下方式获得非零值和索引:

data_csr.data
array([4, 1, 2, 2, 1, 1, 4, 3, 2])

data_csr.indices
array([2, 0, 4, 0, 3, 5, 0, 2, 3])

但我仍然不知道如何计算这两个物体之间的ED。

共有2个答案

程鸿畅
2023-03-14

稀疏矩阵上的成对欧几里德距离在sklearn中实现(正如hpaulj所指出的,scipy实现不适用于稀疏矩阵)。

hpaulj示例示例:

import scipy.sparse
import sklearn.metrics.pairwise
data = [4,1,2,2,1,1,4,3,2]  
col = [0,1,1,2,2,3,4,4,4]
row = [2,0,4,0,3,5,0,2,3]
M = scipy.sparse.csr_matrix((data,(col,row)))
distances = sklearn.metrics.pairwise.pairwise_distances(M,M)

文档:http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_distances.html

颜经艺
2023-03-14

所以让我们创建你的矩阵(太糟糕了,你没有给我输入,我可以复制粘贴)

In [114]: data=[4,1,2,2,1,1,4,3,2]   
In [115]: col=[0,1,1,2,2,3,4,4,4]
In [116]: row=[2,0,4,0,3,5,0,2,3]
In [117]: M=sparse.csr_matrix((data,(col,row)))

In [118]: M
Out[118]: 
<5x6 sparse matrix of type '<type 'numpy.int32'>'
    with 9 stored elements in Compressed Sparse Row format>

In [119]: M.A
Out[119]: 
array([[0, 0, 4, 0, 0, 0],
       [1, 0, 0, 0, 2, 0],
       [2, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1],
       [4, 0, 3, 2, 0, 0]])

In [121]: center=np.array([[0,1,2,2,4,1],[3,4,1,2,4,0]])

那么你是如何计算距离的呢?M. A是(5,6),center是(2,6)。你用这两个数组做什么并不明显。

至于对原始稀疏值的访问,coo格式是最容易理解的。这和我用来创建矩阵的行、列、数据是一样的

In [131]: M.tocoo().data
Out[131]: array([4, 1, 2, 2, 1, 1, 4, 3, 2])

In [132]: M.tocoo().col
Out[132]: array([2, 0, 4, 0, 3, 5, 0, 2, 3])

In [133]: M.tocoo().row
Out[133]: array([0, 1, 1, 2, 2, 3, 4, 4, 4])

csr数据索引indptr数组中存储相同的信息。但是你必须做一些数学运算,才能得出最后2个变量的i,jcsr乘法例程充分利用了这些数组

一般来说,使用csr矩阵进行乘法比加法/减法更好。

我等待进一步澄清。

spatial.distance.cdist(center,M.A, 'euclidean')
Out[156]: 
array([[ 5.09901951,  3.87298335,  5.19615242,  5.        ,  5.91607978],
       [ 7.34846923,  5.38516481,  5.91607978,  6.8556546 ,  6.08276253]])

我们需要做的是研究这个函数,了解它的输入。我们可能不得不超越它的文档,看看代码。

但看看这段代码,我看到了确保xB是2d数组的步骤,列数与xA相同。然后它调用

_distance_wrap.cdist_euclidean_wrap(_convert_to_double(XA),
                                    _convert_to_double(XB), dm)

看起来像一些C代码的包装。我无法想象有什么方法可以给它一个稀疏的矩阵。

您可以迭代行;使用M[[0],:]调用dist。A与M.A[[0],:]相同-除了速度。迭代稀疏矩阵的行有点慢,因为每次迭代都必须构造一个新的稀疏矩阵csrlil是行迭代中最快的两个。

这里有一些可能更快的东西——直接迭代lil格式的属性:

 def foo(a,b,n):
    # make a dense array from data,row
    res = np.zeros((1,n))
    res[0,b]=a
    return res

In [190]: Ml=M.tolil()

In [191]: Ml.data
Out[191]: array([[4], [1, 2], [2, 1], [1], [4, 3, 2]], dtype=object)

In [192]: Ml.rows
Out[192]: array([[2], [0, 4], [0, 3], [5], [0, 2, 3]], dtype=object)

In [193]: rowgen=(foo(a,b,6) for a,b in zip(Ml.data,Ml.rows))

In [194]: np.concatenate([spatial.distance.cdist(center,row, 'euclidean') for row in rowgen],axis=1)
Out[194]: 
array([[ 5.09901951,  3.87298335,  5.19615242,  5.        ,  5.91607978],
       [ 7.34846923,  5.38516481,  5.91607978,  6.8556546 ,  6.08276253]])

现在我将跳过时间测试。

 类似资料:
  • 问题内容: 继一些在线调查(1,2,numpy的,SciPy的,scikit,数学),我已经找到了计算的几种方法 在Python欧氏距离 : 我想知道是否有人可以就 效率* 和 精度 方面认为上述哪一项( 或我未找到的其他任何 理由)提供最佳见解。如果有人知道任何的 资源(S) ,其中讨论的主题,这也将是巨大的。 *** __ 的 背景下 ,我在有趣的是,在计算对数元组之间的欧氏距离,例如之间的距

  • 问题内容: 我在二维空间中有一组点,需要计算每个点到另一个点的距离。 我的点数相对较少,最多不超过100个。但是,由于我需要经常快速地确定这些移动点之间的关系,并且因为我知道遍历这些点可能同样糟糕由于O(n ^ 2)的复杂性,我正在寻找利用numpy矩阵魔术(或scipy)的方法。 就象我的代码中所说的那样,每个对象的坐标都存储在其类中。但是,当我更新类坐标时,也可以用numpy数组更新它们。 我

  • 我想写一个函数来计算中的坐标与中的每个坐标之间的欧氏距离,并通过列生成维度行的距离数组(其中是中的坐标数,是中的坐标数)。 NB:为了简单起见,我不想使用任何其他库。 运行该函数将生成: 我一直在试着运行下面的程序 但我得到以下错误: 非常感谢。

  • 我有一份清单。我想找到所有对和自身之间的欧几里德距离,并创建一个2D numpy数组。当对不同时,其自身之间的距离的位置和值将为0。列表列表的示例:我想要的结果是 x表示差异的值。周期意味着结果应遵循矩阵中所示。我需要python代码方面的帮助。行和列中0、1、2等的数量定义了内部列表索引。

  • 本文向大家介绍求mk矩阵A和nk矩阵的欧几里得距离?相关面试题,主要包含被问及求mk矩阵A和nk矩阵的欧几里得距离?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 先得到矩阵,然后对矩阵A和矩阵分别求出其中每个向量的模平方,并扩展为两个m*k的矩阵和。最终求得新的矩阵,并将此矩阵开平方得到A,B向量集的欧几里得距离。

  • 我有一个矩阵。只有唯一的颜色以不同的权重重复它们自己。从它们中,我得选择一半,另一半必须用从第一个中最接近的元素替换。 我想到了在图像中循环,并搜索最近的颜色为当前的一个。找到后,我把一个换成另一个。 但我有3个循环、、。前两个I循环通过RGB矩阵,第三个用于循环到包含最终颜色的矩阵。这需要一些时间来计算。 可以做些什么来加快它的速度? 循环如下所示: 表示选择为最终颜色的半色。 我可以考虑一些小