我有一个数据帧,其中的行描述了系统中节点之间的值移动。这个数据框看起来像这样:
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
我正在寻找"swap "在发票历史记录中。交换被定义为节点既接收值又将值发送到相同发票号内的另一个节点。在上述数据集中,invoice "a"有两次交换,invoice "d"有一次交换。("to"发送;和"收到"可以是同一行中的同一节点):
index node sent_to sent_value received_from received_value invoice_number
0 B F 20 X 33 a
1 E H 70 A 10 a
2 D H 60 X 43 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