5

我有一个形式的熊猫数据框(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

编辑 请注意,新数据框的行数等于可能的成对组合的总数。此外,为了计算“权重”列,我们只需找到两个列表之间的交集。例如,对于 B&C,元素共享两种颜色:蓝色和黄色。因此,相应行的“权重”为 2。

最快的方法是什么?原始数据框包含大约 28,000 个元素。

4

3 回答 3

6

首先,从数据框开始:

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

现在,应用一个函数来获取集合的并集并找到它的长度。SrcDst列充当对 的查找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不断调用会使它减慢一个档次。

于 2017-07-09T02:40:40.797 回答
5

尝试这个。不是很整洁,但工作。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
于 2017-07-09T02:16:51.920 回答
2
  • 获取一组集合
  • 使用成对索引表示所有组合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
于 2017-07-09T05:51:12.203 回答