首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python创建包含节点对和边缘强度的DataFrame

Python创建包含节点对和边缘强度的DataFrame
EN

Stack Overflow用户
提问于 2018-02-18 21:20:43
回答 2查看 484关注 0票数 4

我正在创建一个简单的网络图,我遇到了一些问题,使我的数据成为正确的形状。

我有一个Pandas DataFrame,其中有两列包含不同实体之间协作的信息。列Project_ID列出项目的ID,Participating_entity列出参与项目的实体。一个有3个实体的项目将占用3行。下面是一个简单的DF示例,列出3个实体在3个项目上的协作:

代码语言:javascript
复制
df =  pd.DataFrame([[1,'a'],[1,'b'],[2,'a'],[2,'c'],[3,'a'],[3,'b'],[3,'c']],  columns = ['Project_ID','Participating_entity']) 

#|---------------------|-------------------------|
#|       Project_ID    | Participating_entity    |
#|---------------------|-------------------------|
#|          1          |            A            |
#|          1          |            B            |
#|          2          |            A            |
#|          2          |            C            |
#|          3          |            A            |
#|          3          |            B            |
#|          3          |            C            |
#|---------------------|-------------------------|

我想要创建一个新的DF来显示Participating_entity对之间的协作数量。上面的简单数据就是。

代码语言:javascript
复制
#|-------------|-----------|--------------------|
#|  Entity_1   | Entity_2  | Num_collaborations |
#|-------------|-----------|--------------------|
#|     A       |      B    |        2           |
#|     A       |      C    |        2           |
#|     B       |      C    |        1           |
#|-------------|-----------|--------------------|

A与B和C各合作两次,B和C各协作一次。协作只应列出一次。例如,A和B之间的连接只应列在A.下面,而B-A不应存在任何行。

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-18 21:38:57

一种方法是将collections.defaultdictitertools.combinations结合使用。可能有一种熊猫特有的方式,但从本质上说,这将是图书馆特有的。

代码语言:javascript
复制
from collections import defaultdict
from itertools import combinations

df_grouped = df.groupby('Project_ID')['Participating_entity'].apply(list).reset_index()

d = defaultdict(int)

for idx, row in df_grouped.iterrows():
    for comb in combinations(row['Participating_entity'], 2):
        d[frozenset(comb)] += 1

# defaultdict(int,
#             {frozenset({'a', 'b'}): 2,
#              frozenset({'a', 'c'}): 2,
#              frozenset({'b', 'c'}): 1})

d = {tuple(sorted(k)): v for k, v in d.items()}

df_out = pd.DataFrame(list(d.items()))\
           .rename(columns={0: 'Entities', 1: 'Num_collaborations'})

df_out = df_out.join(df_out['Entities'].apply(pd.Series))\
               .drop('Entities', 1).rename(columns={0: 'Entity 1', 1: 'Entity 2'})

#    Num_collaborations Entity 1 Entity 2
# 0                   2        a        b
# 1                   2        a        c
# 2                   1        b        c
票数 0
EN

Stack Overflow用户

发布于 2018-02-25 00:35:52

你可以这么做,直接在NetworkX中

代码语言:javascript
复制
In [210]: G = nx.from_pandas_edgelist(df, 'Project_ID', 'Participating_entity')

In [211]: from networkx.algorithms import bipartite

In [212]: W = bipartite.weighted_projected_graph(G, df['Participating_entity'].unique())

In [213]: W.edges(data=True)
Out[213]: EdgeDataView([('a', 'c', {'weight': 2}), ('a', 'b', {'weight': 2}), ('b', 'c', {'weight': 1})])
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48856713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档