从成对列表python创建对称矩阵,用于集群scikit、DBSCAN

从成对列表python创建对称矩阵,用于集群scikit、DBSCAN,python,pandas,scipy,scikit-learn,dbscan,Python,Pandas,Scipy,Scikit Learn,Dbscan,我的目标是使用scikit中的DBSCAN和预计算的相似性矩阵执行聚类。 我有一个功能列表。我两两地为列表生成唯一的对,并有一个计算对之间相似性的函数。现在我想把它转换成一个对称矩阵,可以作为聚类算法的输入。 我认为groupby可能会有所帮助,但我不知道该怎么做。下面是一个示例代码,它给出了具有距离度量的对的列表。原始列表中的id字段是唯一的行标识符 def add_similarity(listdict): random.seed(10) newlistdist=[]

我的目标是使用scikit中的DBSCAN和预计算的相似性矩阵执行聚类。 我有一个功能列表。我两两地为列表生成唯一的对,并有一个计算对之间相似性的函数。现在我想把它转换成一个对称矩阵,可以作为聚类算法的输入。
我认为groupby可能会有所帮助,但我不知道该怎么做。下面是一个示例代码,它给出了具有距离度量的对的列表。原始列表中的id字段是唯一的行标识符

def add_similarity(listdict):
    random.seed(10)
    newlistdist=[]
    for tup_dict in listdict:
        newdict={}
        tup0=tup_dict[0]
        tup1=tup_dict[1]
        for key,value in tup0.items():
            newdict[key +"_1"]=value
        for key,value in tup1.items():
            newdict[key+"_2"]=value 
        newdict["similarity"]=random.random()      
        newlistdist.append(newdict)                   
    return newlistdist


def generatesymm():
    listdict =[{'feature1': 4, 'feature2':2,"id": 100},{'feature1': 3, 'feature2': 2,"id":200},{'feature1': 4, 'feature2':2,"id": 300}]
    pairs=list(itertools.combinations(listdict, 2) )
    newlistdict=add_similarity(pairs)
如果我运行这个代码

    [{'id_2': 200, 'feature1_2': 3, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.571, 'id_1': 100},     


{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 4, 'similarity': 0.42, 'id_1': 100},   


{'id_2': 300, 'feature1_2': 4, 'feature2_2': 2, 'feature2_1': 2, 'feature1_1': 3, 'similarity': 0.578, 'id_1': 200}]
我需要的输出

          100       200       300


100        1         0.571      0.42  


200        0.571      1          0.578


300        0.428      0.578       1

我不清楚
id\u3
来自哪里,但下面是制作数据帧的一种方法。诀窍是使用numpy索引到矩阵的上下三角部分

In [679]:
import numpy as np
import pandas as pd
similarities = [x["similarity"] for x in newlistdict]
names = ['id_'+str(x) for x in range(1,4)]
n = len(similarities)
iuu = np.mask_indices(3, np.triu, 1)
iul = np.mask_indices(3, np.tril, -1)
mat = np.eye(n)
mat[iuu] = similarities
mat[iul] = similarities
df = pd.DataFrame(mat,columns=names)
df.index = names
df

Out[679]:
        id_1        id_2        id_3
id_1    1.000000    0.896082    0.897818
id_2    0.896082    1.000000    0.186298
id_3    0.897818    0.186298    1.000000

(这些值与您的问题不同,因为我不知道您使用的随机种子。)

原始列表中的id字段(在成对之前)包含记录的唯一id。成对之后,每一行都由colnames id_1、id_2中的值唯一标识。最后,[id_1][id_3]应该对id=1和id=3的记录具有相似性值。如果原始列表有5条记录,则两两给出10个组合。矩阵是10*10,其中行和列名称对应于原始id字段的唯一值。使用
for
循环,并在
[x,y]
ad oncein
[y,x]
中存储一次值如何?@对于大型矩阵,任何使用for循环的鼠标都不太可行。您可能会遇到内存问题。@ColinAnthony内存问题与是否使用for循环无关。预计算的矩阵方法通常规模很小,但这是他的要求。