我有一个df1
,其中包含一些item_id
,以及每个项目的一些值(称为“节点”):
df1 = pd.DataFrame({'item_id':['1','1','1','2','2','2','3','3'],'nodes':['a','b','c','d','a','e','f','g']})
和一个df2
,这是一个“向量”列表,其中每行是一个节点元组(可以在df1
中,但其中一些不是):
df2=pd.DataFrame({'vectors':[('a','b'),('b','c'),('d','f'),('e','b')]})
我需要计算df1
中不同的item_id
的数量,这些item_id
在df2
中至少有一个向量,因为向量可以从该项目的所有可能的节点组合中构造出来。
例如,item_id = 1
具有节点[a,b,c]
,因此可以形成这些向量:[(a,b),(a,c),(b,a),(b,c),(c,a),(c,b)]
。由于向量(a,b)
和(b,c)
存在于df2
中,那么我应该计数item_id = 1
。但是,我不应该计数item_id = 2
,因为从所有可以由其节点组合形成的向量中,没有一个在df2
中。
我不知道如何才能做到这一点。我可以获得所有可能的节点组合列表,以形成df1
中第一个item_id
的不同向量,使用:
from itertools import product
nodes_fa=df1[df1.item_id=="1"].nodes.to_list()
vectors_fa = pd.DataFrame(product(nodes_fa,nodes_fa),columns=['u','v'],dtype='str')
vectors_fa['vector'] = vectors_fa[["u", "v"]].agg(tuple, axis=1)
vectors_fa = vectors_fa[['vector']]
display(vectors_fa)
但是我不知道如何将其扩展到所有的item_id
,也不知道如何检查这个列表中的任何值是否在循环中的df2
中。
任何帮助都将不胜感激。
2条答案
按热度按时间ha5z0ras1#
您可以使用
itertools.combinations
和groupby.apply
,并在set
/frozenset
的帮助下:要考虑无向边(
('a', 'b')
==('b', 'a')
):对于有向边(
('a', 'b')
!=('b', 'a')
):输出:
1
使用pandas函数的替代方案(可能效率较低):
5vf7fwbs2#
我想提出一个使用合并而不是依赖于
apply
的解决方案,这取决于存在多少个item_id
值,以及每个item_id
有多少行,它可能也会更好地提高性能。