首页 > 解决方案 > Pandas Edgelist 到 NetworkX 权重聚合

问题描述

亲爱的,

我在 pandasdataframe 中有以下边缘列表(大约 400 万行,仅显示问题的描述):

客户_A 客户_B 重量
客户 1 客户 2 320
客户 1 客户 3 400
客户 2 客户 1 100

如您所见,客户 1 和客户 2 之间存在双向连接,当我通过以下方式创建 networkx 图时:

G = nx.from_pandas_edgelist(df, 'Customer_A', 'Customer_B', 'Weight')

networkx 只采用两个权重中的一个(我的猜测是它遇到的第一个),而忽略另一个。我的问题是我如何才能真正得到一个具有两个权重总和的图表(在这种情况下,客户 1 和客户 2 之间的连接权重为 420)。

我尝试在数据帧上创建一个带有枢轴的邻接矩阵,但考虑到 400 万行,我的内存不足。

我正在考虑分成两张图——一张只存在两种方式的关系,一张只有一种方式,但我认为他不会解决我的问题。

先感谢您!

问候, 赫里斯托

标签: pythonpandasnetworkx

解决方案


我的猜测是你最好在 Pandas 中进行预处理——你称之为“解决方法”。据我所知,NetworkX 中没有用于这种转换的简单工具/方法。(但是,当然,这并不意味着没有!)。我所知道的 NetworkX 中的所有解决方案都包括迭代边缘。最好的办法是在合理大小的样本上测试两种方法的性能。

“解决方法”的两个想法:

df = df.groupby(
         df[['Customer_A', 'Customer_B']].apply(
             lambda row: '|'.join(sorted(row)),
             axis='columns'
         )
     ).sum().reset_index(drop=False).rename(columns={'index': 'Edges'})
df[['Customer_A', 'Customer_B']] = df.Edges.str.split('|', expand=True)
df.drop(columns=['Edges'], inplace=True)
G = nx.from_pandas_edgelist(df, 'Customer_A', 'Customer_B', 'Weight')

或者

df = df.groupby(
         df[['Customer_A', 'Customer_B']].apply(
             lambda row: tuple(sorted(row)),
             axis='columns'
         )
     ).sum().reset_index(drop=False).rename(columns={'index': 'Edges'})
df[['Customer_A', 'Customer_B']] = pd.DataFrame(df.Edges.to_list())
df.drop(columns=['Edges'], inplace=True)
G = nx.from_pandas_edgelist(df, 'Customer_A', 'Customer_B', 'Weight')

推荐阅读