Python 如何使用三角矩阵使np.where更有效?

Python 如何使用三角矩阵使np.where更有效?,python,numpy,scipy,itertools,Python,Numpy,Scipy,Itertools,我得到了这个代码,其中距离是一个下三角矩阵,定义如下: distance = np.tril(scipy.spatial.distance.cdist(points, points)) def make_them_touch(distance): """ Return the every distance where two points touched each other. See example below. """ thresholds = np.un

我得到了这个代码,其中距离是一个下三角矩阵,定义如下:

distance = np.tril(scipy.spatial.distance.cdist(points, points))  
def make_them_touch(distance):
    """
    Return the every distance where two points touched each other. See example below.
    """
    thresholds = np.unique(distance)[1:] # to avoid 0 at the beginning, not taking a lot of time at all
    result = dict()
    for t in thresholds:
            x, y = np.where(distance == t)
            result[t] = [i for i in zip(x,y)]
    return result
我的问题是np.where对于大矩阵(例如2000*100)非常慢。
如何通过改进np.where或更改算法来加速此代码

编辑:正如所指出的,这里的最佳优化不是生成平方矩阵,而是使用迭代器

例子:
更新1:这里是一个上三角距离矩阵的片段(这其实并不重要,因为距离矩阵总是对称的):

结果:

In [111]: res
Out[111]:
{1.4142135623730951: (0, 1),
 4.69041575982343: (0, 2),
 4.898979485566356: (1, 2)}

更新2:此版本将支持远距离复制:

In [164]: import pandas as pd
首先,我们构建一个熊猫系列:

In [165]: s = pd.Series(list(combinations(range(len(points)), 2)), index=pdist(points))

In [166]: s
Out[166]:
2.0     (0, 1)
6.0     (0, 2)
12.0    (0, 3)
4.0     (1, 2)
10.0    (1, 3)
6.0     (2, 3)
dtype: object
现在我们可以按索引分组并生成坐标列表:

In [167]: s.groupby(s.index).apply(list)
Out[167]:
2.0             [(0, 1)]
4.0             [(1, 2)]
6.0     [(0, 2), (2, 3)]
10.0            [(1, 3)]
12.0            [(0, 3)]
dtype: object

PS这里的主要思想是,如果要在之后将其展平并消除重复项,则不应构建平方距离矩阵。

@politinsa,你想实现什么?您的问题不太清楚。您的解决方案非常快,谢谢您的更新!我正在尝试获得一个新的过滤/持久性。这是一个@politinsa,很高兴我能帮忙:)@politinsa,你当然能!如果您能在代码中留下此帖子的链接作为注释,我将不胜感激;-)已经完成;)要评论您的答案,这里的缺点是,如果一个具有相同值的多个距离,则最后一个会删除前一个。但无论如何,即使使用列表也比我的函数快无穷多。
In [165]: s = pd.Series(list(combinations(range(len(points)), 2)), index=pdist(points))

In [166]: s
Out[166]:
2.0     (0, 1)
6.0     (0, 2)
12.0    (0, 3)
4.0     (1, 2)
10.0    (1, 3)
6.0     (2, 3)
dtype: object
In [167]: s.groupby(s.index).apply(list)
Out[167]:
2.0             [(0, 1)]
4.0             [(1, 2)]
6.0     [(0, 2), (2, 3)]
10.0            [(1, 3)]
12.0            [(0, 3)]
dtype: object