Python 3.x 加快循环查找速度:Numpy相当于熊猫合并?

Python 3.x 加快循环查找速度:Numpy相当于熊猫合并?,python-3.x,pandas,numpy,duplicates,graph-theory,Python 3.x,Pandas,Numpy,Duplicates,Graph Theory,我从有向图中的父/子(边)关系列表开始,如下所示: import numpy as np import pandas as pd df = pd.DataFrame(columns=['parent', 'child']) df.loc[0] = (0, 1) df.loc[1] = (1, 2) df.loc[2] = (2, 0) 您可以立即看到我们有循环0-->1-->2-->0。我希望能够在数据帧中检测到这些循环,就像我所做的那样。到目前为止,我的策略(在我大得多的数据集上运行得太慢

我从有向图中的父/子(边)关系列表开始,如下所示:

import numpy as np
import pandas as pd

df = pd.DataFrame(columns=['parent', 'child'])
df.loc[0] = (0, 1)
df.loc[1] = (1, 2)
df.loc[2] = (2, 0)
您可以立即看到我们有循环
0-->1-->2-->0
。我希望能够在数据帧中检测到这些循环,就像我所做的那样。到目前为止,我的策略(在我大得多的数据集上运行得太慢)是利用pandas merge函数:

def find_loops(link_df: pd.DataFrame) -> dict:
    link_df.columns = ['0', '1']
    # Max number of iterations - don't expect to need this many.
    num_appts = len(set(link_df['0']) | set(link_df['1']))
    new_df = pd.DataFrame(link_df)
    for i in range(num_appts):
        new_df = new_df.merge(link_df, left_on=str(i+1), right_on='0', how='inner')
        new_df.drop(columns='0_y', inplace=True)
        new_df.columns = [str(j) for j in range(i+3)]
这使我在每次循环迭代时都能看到
new_df.values
中的数组,其中包含长度不断增加的路径(
i+3
)。如果路径结束并且没有循环,那么
merge
函数会自动删除该行,这非常好。为了检测循环,我沿着一行
new_df.values
查找重复的值,如下所示:

        paths = new_df.values.astype(np.int32)
        is_loop = pd.Series(paths[:, 0] == paths[:, 1])
        width = i + 3
        for j in range(width - 1):
            for k in range(j+1, width):
                is_loop = is_loop | (paths[:, j] == paths[:, k])

find_loops(df)
我需要这段代码运行得更快。有什么想法吗?我的一个想法是尝试在numpy中实现pandas
merge
函数,但我不知道哪一个函数能够实现这一点

我已经尝试了
复制
函数、
计数器
对象和
np.unique
函数,它们都远没有我这里的速度快

我见过,也见过;这些功能中有一些是可以使用的吗?

您可以尝试:

import pandas as pd
import networkx as nx

df = pd.DataFrame(columns=['parent', 'child'])
df.loc[0] = (0, 1)
df.loc[1] = (1, 2)
df.loc[2] = (2, 0)


dg = nx.from_pandas_edgelist(df, source='parent', target='child', create_using=nx.DiGraph)
res = list(nx.simple_cycles(dg))
print(res)
输出

[[0, 1, 2]]
从以下文件:

求有向图的简单圈(初等回路)

简单循环或基本回路是一条没有节点的闭合路径 出现两次。如果两个基本电路不相同,则它们是不同的 彼此的循环置换


在上面的文档链接中,有一些指向可能感兴趣的其他算法的链接。

您可能希望使用networkx,尤其是@Danimesjo,非常好!我会检查的。我认为这会起作用,但我需要提高我的整体结构的效率,比如只创建一次有向图,并从中添加或删除边,而不是每次都重新创建整个结构。我会告诉你的。正如你所料,我的循环速度比我实现循环查找之前慢了一点,但是这个解决方案,再加上我上面提到的,是一个可以接受的速度。非常感谢!