如何获得Python中每个人最具共同特征的人的列表?
我有一个数据框,看起来像(下面1表示有特征,0表示没有): 我想要一个函数,为每个人返回具有最多共同特征的前10名 因此,对于人A,输出可以是:如何获得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
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数组,然后进行标量积
#如果尚未完成
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)