如何获得Python中每个人最具共同特征的人的列表?

如何获得Python中每个人最具共同特征的人的列表?,python,Python,我有一个数据框,看起来像(下面1表示有特征,0表示没有): 我想要一个函数,为每个人返回具有最多共同特征的前10名 因此,对于人A,输出可以是: D (3 traits), B (2 traits), C(1 trait), E(1 trait) 我认为有一个矩阵,它看起来像是编码每个人与其他人有多少共同点,这将是一个良好的开端: A B C D E A 4 2 1 3 1 B 2 4 1 1 0 C 1 1 4 1 0 D 3 1 1

我有一个数据框,看起来像(下面1表示有特征,0表示没有):

我想要一个函数,为每个人返回具有最多共同特征的前10名

因此,对于人A,输出可以是:

D (3 traits), B (2 traits), C(1 trait), E(1 trait)
我认为有一个矩阵,它看起来像是编码每个人与其他人有多少共同点,这将是一个良好的开端:

   A  B  C  D  E
A  4  2  1  3  1
B  2  4  1  1  0
C  1  1  4  1  0  
D  3  1  1  4  1
E  1  0  0  1  4

但我不知道如何实现这一点,也不知道这叫什么。

我想如果没有
iterrows
的话,你是做不到的, 首先得到你所说的矩阵(
A*A.t
),然后用
nlargest
获得每行的顶部列(并删除对角线,因为你不想把一个人算作最近的邻居)

将熊猫作为pd导入
将numpy作为np导入
NB_最相似=3
df=pd.DataFrame(
数据={'t_1':[1,0,0,1,0],'t_2':[1,1,1,0],
‘t_3’:[1,1,0,0,0],‘t_4’:[1,0,0,1,1]},
索引=['A','B','C','D','E']
)
产品=测向点(测向点T)
prod.iloc[[np.arange(prod.shape[0])]*2]=0
共同特征=dict()
对于人名,prod.iterrows()中的com\u traits:
特征=[
(邻居,特征)对于邻居,特征
在com_traits.nlagest(NB_最相似).items()中
如果特征>0
]
普通特征[人名]=特征
共同特征
#{'A':[('D',3),('B',2),('C',1)],
#"B:["A,2","C,1","D,1"],,
#‘C’:[('A',1),('B',1),('D',1)],
#“D”:[('A',3),('B',1),('C',1)],
#“E”:[('A',1),('D',1)]]

这更像是一个线性代数的答案,但如果你想知道人a和人B之间的共同特征的数量,你可以计算人a的线向量和人B的线向量的标量积(这只起作用,因为你的矩阵是二进制矩阵)

我不知道您使用的是什么框架/库,但如果您使用的是pandas,您可以轻松提取线向量并将其转换为numpy数组,然后进行标量积

  • 创建一个数据帧
  • 使用矩阵乘法创建常见特征的矩阵(您描述的)
  • 为每个人打印你想要的字符串(最具共同特征的前10位人物)
  • 输出 尝试:

    #如果尚未完成
    df.set_索引(“人”,原地=真)
    res=(df@df.T).stack().reset_索引(级别=1)
    res=res.loc[res[“Person”].ne(res.index)&res[0].gt(0)].sort_值(0,升序=False).groupby(level=0).apply(lambda x:list(x.values))
    
    产出:

    >res
    人
    A[[D,3],[B,2],[C,1],[E,1]]
    B[[A,2],[C,1],[D,1]]
    C[[A,1],[B,1],[D,1]]
    D[[A,3],[B,1],[C,1],[E,1]]
    E[[A,1],[D,1]]
    数据类型:对象
    
    和您的函数(结果按降序排列):

    >>res.loc['C']
    [array(['A',1],dtype=object),array(['B',1],dtype=object),array(['D',1],dtype=object)]
    
    每个人都有单独的数据框吗?@IoaTzimas没有,所有人都有一个数据框,列显示他们是否有特征。好的,列中的特征以某种方式与人相关?你如何把一排的人和其他人联系起来?@IoaTzimas如果一个人的特质是1,那么这个人就有这个特质。所以,我想为每个人列出一份拥有最多共同特征的人的名单。你是否认为“缺乏”一个共同特征?当你把E和E比较并给它打4分时,你似乎是这样做的,但在C和E比较中,你给它打了0分,这与这个模式相反?如果你只想寻找“common 1”,那就更简单了……谢谢,它很管用。这也会返回没有共同特征的人,有没有一种方法可以过滤出至少有一个共同特征的人?是的,我调整了我的答案-看吧,谢谢。有没有一种方法可以说明有多少特征与此相同?例如,类似于“A”的东西:[“D”(3个特征),“B”(2个特征)]当然,除了得到最大的索引,你还可以得到它的值@我编辑了答案谢谢你。有没有一种方法可以筛选出至少有一个共同特征的人?你能用一个例子说明你的要求吗?对不起,我不清楚。基本上,如果有0个共同特征的人没有显示出来,这是有意义的。你的意思是说,你想要这个输出,而不是
    E:A(1个特征),D(1个特征),B(0个特征),C(0个特征)
    你想要这个输出
    E:A(1个特征),D(1个特征)
    ?是的,没错
       A  B  C  D  E
    A  4  2  1  3  1
    B  2  4  1  1  0
    C  1  1  4  1  0  
    D  3  1  1  4  1
    E  1  0  0  1  4
    
    import pandas as pd
    df = pd.DataFrame(data=[[1, 1, 1, 1],
                            [0, 1, 1, 0],
                            [0, 1, 0, 0],
                            [1, 1, 0, 1],
                            [0, 0, 0, 1]],
                     index=['A', 'B', 'C', 'D', 'E',],
                     columns=['Trait_1', 'Trait_2', 'Trait_3', 'Trait_4'])
    
    common_traits = df @ df.T
    
    n = 10
    for index, row in common_traits.iterrows():
        top10 = row.drop(index).nlargest(n)
        top10 = top10[top10 > 0]
        string = ', '.join(top10.index + top10.map(lambda x: f' ({x} trait{"s" if x != 1 else ""})'))
        print(f'{index}: {string}')
    
    A: D (3 traits), B (2 traits), C (1 trait), E (1 trait)
    B: A (2 traits), C (1 trait), D (1 trait)
    C: A (1 trait), B (1 trait), D (1 trait)
    D: A (3 traits), B (1 trait), C (1 trait), E (1 trait)
    E: A (1 trait), D (1 trait)