如何从 pandas 数据框创建边列表?
How to create an edge list from pandas dataframe?
我有一个 pandas 数据框 (df) 的形式 -
Col1
A [Green,Red,Purple]
B [Red, Yellow, Blue]
C [Brown, Green, Yellow, Blue]
我需要将其转换为边缘列表,即以下形式的数据框:
Source Target Weight
A B 1
A C 1
B C 2
编辑
请注意,新数据框的行数等于可能的成对组合的总数。此外,要计算 'Weight' 列,我们只需找到两个列表之间的交集。例如,对于 B&C,元素共享两种颜色:蓝色和黄色。因此,对应行的 'Weight' 为 2.
最快的方法是什么?原始数据框包含大约 28,000 个元素。
试试这个。不是很整洁,但工作。 PS: 最终输出你可以调整它,我没有删除列并更改列名称
import pandas as pd
df=pd.DataFrame({"Col1":[['Green','Red','Purple'],['Red', 'Yellow', 'Blue'],['Brown', 'Green', 'Yellow', 'Blue']],"two":['A','B','C']})
df=df.set_index('two')
del df.index.name
from itertools import combinations
DF=pd.DataFrame()
dict1=df.T.to_dict('list')
DF=pd.DataFrame(data=[x for x in combinations(df.index, 2)])
DF['0_0']=DF[0].map(df['Col1'])
DF['1_1']=DF[1].map(df['Col1'])
DF['Weight']=DF.apply(lambda x : len(set(x['0_0']).intersection(x['1_1'])),axis=1)
DF
Out[174]:
0 1 0_0 1_1 Weight
0 A B [Green, Red, Purple] [Red, Yellow, Blue] 1
1 A C [Green, Red, Purple] [Brown, Green, Yellow, Blue] 1
2 B C [Red, Yellow, Blue] [Brown, Green, Yellow, Blue] 2
首先,从数据帧开始:
from itertools import combinations
df = pd.DataFrame({
'Col1': [['Green','Red','Purple'],
['Red', 'Yellow', 'Blue'],
['Brown', 'Green', 'Yellow', 'Blue']]
}, index=['A', 'B', 'C'])
df['Col1'] = df['Col1'].apply(set)
df
Col1
A {Purple, Red, Green}
B {Red, Blue, Yellow}
C {Green, Yellow, Blue, Brown}
Col1
中的每个列表都已转换为一个集合,以便有效地找到并集。接下来,我们将使用 itertools.combinations
创建 df
:
中所有行的成对组合
df1 = pd.DataFrame(
data=list(combinations(df.index.tolist(), 2)),
columns=['Src', 'Dst'])
df1
Src Dst
0 A B
1 A C
2 B C
现在,应用一个函数来获取集合的并集并找到它的长度。 Src
和 Dst
列充当对 df
的查找。
df1['Weights'] = df1.apply(lambda x: len(
df.loc[x['Src']]['Col1'].intersection(df.loc[x['Dst']]['Col1'])), axis=1)
df1
Src Dst Weights
0 A B 1
1 A C 1
2 B C 2
我建议一开始就设置转换。每次都将您的列表即时转换为集合既昂贵又浪费。
为了加快速度,您可能想要 也 将集合复制到新数据框中的两列中,因为不断调用 df.loc
会减慢一个档次.
- 获取集合数组
- 使用
np.triu_indices
获取表示所有组合的成对索引
- 使用
&
运算符获取成对交集并通过理解获取长度
c = df.Col1.apply(set).values
i, j = np.triu_indices(c.size, 1)
pd.DataFrame(dict(
Source=df.index[i],
Target=df.index[j],
Weight=[len(s) for s in c[i] & c[j]]
))
Source Target Weight
0 A B 1
1 A C 1
2 B C 2
我有一个 pandas 数据框 (df) 的形式 -
Col1
A [Green,Red,Purple]
B [Red, Yellow, Blue]
C [Brown, Green, Yellow, Blue]
我需要将其转换为边缘列表,即以下形式的数据框:
Source Target Weight
A B 1
A C 1
B C 2
编辑 请注意,新数据框的行数等于可能的成对组合的总数。此外,要计算 'Weight' 列,我们只需找到两个列表之间的交集。例如,对于 B&C,元素共享两种颜色:蓝色和黄色。因此,对应行的 'Weight' 为 2.
最快的方法是什么?原始数据框包含大约 28,000 个元素。
试试这个。不是很整洁,但工作。 PS: 最终输出你可以调整它,我没有删除列并更改列名称
import pandas as pd
df=pd.DataFrame({"Col1":[['Green','Red','Purple'],['Red', 'Yellow', 'Blue'],['Brown', 'Green', 'Yellow', 'Blue']],"two":['A','B','C']})
df=df.set_index('two')
del df.index.name
from itertools import combinations
DF=pd.DataFrame()
dict1=df.T.to_dict('list')
DF=pd.DataFrame(data=[x for x in combinations(df.index, 2)])
DF['0_0']=DF[0].map(df['Col1'])
DF['1_1']=DF[1].map(df['Col1'])
DF['Weight']=DF.apply(lambda x : len(set(x['0_0']).intersection(x['1_1'])),axis=1)
DF
Out[174]:
0 1 0_0 1_1 Weight
0 A B [Green, Red, Purple] [Red, Yellow, Blue] 1
1 A C [Green, Red, Purple] [Brown, Green, Yellow, Blue] 1
2 B C [Red, Yellow, Blue] [Brown, Green, Yellow, Blue] 2
首先,从数据帧开始:
from itertools import combinations
df = pd.DataFrame({
'Col1': [['Green','Red','Purple'],
['Red', 'Yellow', 'Blue'],
['Brown', 'Green', 'Yellow', 'Blue']]
}, index=['A', 'B', 'C'])
df['Col1'] = df['Col1'].apply(set)
df
Col1
A {Purple, Red, Green}
B {Red, Blue, Yellow}
C {Green, Yellow, Blue, Brown}
Col1
中的每个列表都已转换为一个集合,以便有效地找到并集。接下来,我们将使用 itertools.combinations
创建 df
:
df1 = pd.DataFrame(
data=list(combinations(df.index.tolist(), 2)),
columns=['Src', 'Dst'])
df1
Src Dst
0 A B
1 A C
2 B C
现在,应用一个函数来获取集合的并集并找到它的长度。 Src
和 Dst
列充当对 df
的查找。
df1['Weights'] = df1.apply(lambda x: len(
df.loc[x['Src']]['Col1'].intersection(df.loc[x['Dst']]['Col1'])), axis=1)
df1
Src Dst Weights
0 A B 1
1 A C 1
2 B C 2
我建议一开始就设置转换。每次都将您的列表即时转换为集合既昂贵又浪费。
为了加快速度,您可能想要 也 将集合复制到新数据框中的两列中,因为不断调用 df.loc
会减慢一个档次.
- 获取集合数组
- 使用
np.triu_indices
获取表示所有组合的成对索引
- 使用
&
运算符获取成对交集并通过理解获取长度
c = df.Col1.apply(set).values
i, j = np.triu_indices(c.size, 1)
pd.DataFrame(dict(
Source=df.index[i],
Target=df.index[j],
Weight=[len(s) for s in c[i] & c[j]]
))
Source Target Weight
0 A B 1
1 A C 1
2 B C 2