Python 优化在数据帧中查找行对

Python 优化在数据帧中查找行对,python,pandas,dataframe,optimization,Python,Pandas,Dataframe,Optimization,我有一个数据框,其中的行描述了系统中节点之间的值移动。此数据帧如下所示: index from_node to_node value invoice_number 0 A E 10 a 1 B F 20 a 2 C G 40 c 3 D H 60 d 4 E

我有一个数据框,其中的行描述了系统中节点之间的值移动。此数据帧如下所示:

index   from_node   to_node  value  invoice_number
0       A           E        10     a
1       B           F        20     a
2       C           G        40     c
3       D           H        60     d
4       E           I        35     c
5       X           D        43     d
6       Y           F        50     d
7       E           H        70     a
8       B           A        55     b
9       X           B        33     a
我希望在发票历史记录中找到“掉期”。交换定义为一个节点同时接收一个值并将其发送到同一发票号内的另一个节点。在上述数据集中,发票“a”中有两个掉期,发票“d”中有一个掉期(“发送到”和“接收自”可能是同一行中的同一节点):

我通过迭代数据集中所有唯一的发票编号,然后迭代该发票编号中的每一行来查找对,从而解决了这个问题:

import pandas as pd

df = pd.DataFrame({
    'from_node':['A','B','C','D','E','X','Y','E','B','X'],
    'to_node':['E','F','G','H','I','D','F','H','A','B'],
    'value':[10,20,40,60,35,43,50,70,55,33],
    'invoice_number':['a','a','c','d','c','d','d','a','b','a'],
    }) 

invoices = set(df.invoice_number)

list_df_swap = []
for invoice in invoices:
    df_inv = df[df.invoice_number.isin([invoice])]
    for r in df_inv.itertuples():
        df_is_swap = df_inv[df_inv.to_node.isin([r.from_node])]
        if len(df_is_swap.index) == 1:
            swap = {'node': r.from_node,
                    'sent_to': r.to_node,
                    'sent_value': r.value,
                    'received_from': df_is_swap.iloc[0]['from_node'],
                    'received_value': df_is_swap.iloc[0]['value'],
                    'invoice_number': r.invoice_number
                    }
            list_df_swap.append(pd.DataFrame(swap, index = [0]))
        
df_swap = pd.concat(list_df_swap, ignore_index = True)

整个数据集由数亿行组成,这种方法不是很有效。是否有办法使用某种矢量化解决方案或其他方法来解决此问题,以加快执行时间?

计算所有可能的掉期,不计入发票号:

swaps = df.merge(df, left_on='from_node', right_on='to_node')
columns = ['from_node_x', 'to_node_x', 'value_x', 'from_node_y', 'value_y', 
           'invoice_number_x']

swaps[swaps.invoice_number_x == swaps.invoice_number_y][columns]
#  from_node_x to_node_x  value_x from_node_y  value_y invoice_number_x
#1           B         F       20           X       33                a
#3           D         H       60           X       43                d
#5           E         H       70           A       10                a
然后选择具有相同发票号的发票:

swaps = df.merge(df, left_on='from_node', right_on='to_node')
columns = ['from_node_x', 'to_node_x', 'value_x', 'from_node_y', 'value_y', 
           'invoice_number_x']

swaps[swaps.invoice_number_x == swaps.invoice_number_y][columns]
#  from_node_x to_node_x  value_x from_node_y  value_y invoice_number_x
#1           B         F       20           X       33                a
#3           D         H       60           X       43                d
#5           E         H       70           A       10                a

谢谢你,DYZ,一个简单有效的答案,比我的答案快3倍左右!