如何基于Pandas DataFrame生成含双向计数的加权有向边列表?
问题描述
给定如下Pandas DataFrame(df):
import pandas as pd df = pd.DataFrame([ ['A', 'B', '1'], ['A', 'B', '2'], ['B', 'A', '41'], ['A', 'C', '11'], ['C', 'B', '3'], ['B', 'D', '4'], ['D', 'B','51'] ], columns=('station_i', 'station_j','UID'))
通过以下代码得到df2:
df2=df.groupby(by=['station_i', 'station_j']).size().to_frame(name = 'counts_ij').reset_index()
df2的输出结果为:
station_i station_j counts_ij 0 A B 2 1 A C 1 2 B A 1 3 B D 1 4 C B 1 5 D B 1
需要生成df3,将值相同但方向相反的边对合并,新增counts_ji列记录反向边的计数(无反向边则为0),目标df3如下:
station_i station_j counts_ij counts_ji 0 A B 2 1 1 A C 1 0 2 C B 1 0 3 B D 1 1
解决方案
可以通过自连接+去重逻辑实现需求,具体步骤如下:
- 创建反向边的临时表,互换
station_i和station_j字段,并重命名计数列:
reverse_df = df2.rename(columns={ 'station_i': 'station_j', 'station_j': 'station_i', 'counts_ij': 'counts_ji' })
- 将原表与反向表做左连接,匹配对应反向边的计数:
merged_df = df2.merge(reverse_df, on=['station_i', 'station_j'], how='left')
- 填充缺失值:无反向边的记录,
counts_ji会显示为NaN,将其填充为0并转为整数类型:
merged_df['counts_ji'] = merged_df['counts_ji'].fillna(0).astype(int)
- 去重处理:为避免同时保留正向和反向边(比如
A-B和B-A),生成统一的边标识,然后每组只保留一条记录:
# 生成边的唯一标识,正向/反向边的标识一致 merged_df['edge_key'] = merged_df.apply( lambda x: '-'.join(sorted([x['station_i'], x['station_j']])), axis=1 ) # 去重,保留每组中首次出现的记录 df3 = merged_df.drop_duplicates(subset='edge_key', keep='first').drop(columns='edge_key').reset_index(drop=True)
执行后得到的df3完全符合需求:
station_i station_j counts_ij counts_ji 0 A B 2 1 1 A C 1 0 2 C B 1 0 3 B D 1 1
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

