Python Pandas - 创建包含节点对和边强度的DataFrame
Python Pandas - Create DataFrame that contains node pairs and edge strength
我正在创建一个简单的网络图,但在将我的数据设置为正确的形状时遇到了一些问题。
我有一个 Pandas DataFrame,其中包含两列,其中包含有关不同实体之间协作的信息。 Project_ID 列列出了项目的 ID,Participating_entity 列列出了参与该项目的一个实体。具有 3 个实体的项目将占用 3 行。这是一个简单的 DF 示例,列出了 3 个项目中 3 个实体之间的协作:
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 对之间的协作次数。对于上面的简单数据。
#|-------------|-----------|--------------------|
#| Entity_1 | Entity_2 | Num_collaborations |
#|-------------|-----------|--------------------|
#| A | B | 2 |
#| A | C | 2 |
#| B | C | 1 |
#|-------------|-----------|--------------------|
A 与 B 和 C 各合作了两次。B 和 C 合作了一次。协作应仅列出一次。例如,A 和 B 之间的连接应仅列在 A-B 下,B-A 不应存在任何行。
提前致谢!
一种方法是使用 collections.defaultdict
combined with itertools.combinations
。可能有一种 pandas-specific 方式,但从本质上讲,这将是 library-specific.
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
你可以的directly in NetworkX:
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})])
我正在创建一个简单的网络图,但在将我的数据设置为正确的形状时遇到了一些问题。
我有一个 Pandas DataFrame,其中包含两列,其中包含有关不同实体之间协作的信息。 Project_ID 列列出了项目的 ID,Participating_entity 列列出了参与该项目的一个实体。具有 3 个实体的项目将占用 3 行。这是一个简单的 DF 示例,列出了 3 个项目中 3 个实体之间的协作:
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 对之间的协作次数。对于上面的简单数据。
#|-------------|-----------|--------------------|
#| Entity_1 | Entity_2 | Num_collaborations |
#|-------------|-----------|--------------------|
#| A | B | 2 |
#| A | C | 2 |
#| B | C | 1 |
#|-------------|-----------|--------------------|
A 与 B 和 C 各合作了两次。B 和 C 合作了一次。协作应仅列出一次。例如,A 和 B 之间的连接应仅列在 A-B 下,B-A 不应存在任何行。
提前致谢!
一种方法是使用 collections.defaultdict
combined with itertools.combinations
。可能有一种 pandas-specific 方式,但从本质上讲,这将是 library-specific.
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
你可以的directly in NetworkX:
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})])