2017-07-09 10 views
-1

私は、フォームのデータフレーム、すなわち、エッジリストにこれを変換する必要があるフォーム -pandasデータフレームからエッジリストを作成するには?

Col1 
A [Green,Red,Purple] 
B [Red, Yellow, Blue] 
C [Brown, Green, Yellow, Blue] 

のパンダのデータフレーム(DF)を持っている:

Source Target Weight 
    A   B   1 
    A   C   1 
    B   C   2 

EDIT 注意していること新しいデータフレームは、可能なペアごとの組み合わせの総数に等しい行を有する。また、「Weight」列を計算するために、2つのリスト間の交差点を見つけるだけです。例えば、B & Cの場合、要素は青と黄の2色を共有します。したがって、対応する行の「重み」は2です。

これを行う最も簡単な方法は何ですか?元のデータフレームには約28,000の要素が含まれています。

+2

を介して長さを取得するnp.triu_indices

  • 使用&演算子を使用して、すべての組み合わせを表すペアワイズインデックスを得ます申し訳ありませんが、最初から2番目にどのようにしたいのかは不明です。 –

  • +0

    @cᴏʟᴅseach各要素のリストはペアごとに比較されます。例えば、A-Bの場合、要素は共通の要素(赤色)を持ちます。したがって、Source-A Target-B行の重みは1です。合計で、新しいデータフレームは元のデータフレーム行のすべてのペアごとの組み合わせを持ちます。 – Melsauce

    +0

    あなたは28kの要素を言うとき、行/ノードを意味しますか?その場合は、すべての組み合わせ生成アプローチを実行するとかなり大規模になります(https://www.google.com/search?q=28000+choose+2&oq=28000+cho&aqs=chrome.0.69i59j69i57j0)。6150j0j8&sourceid = chrome&ie = UTF-8) –

    答えて

    3

    に名前を付ける列を変更:

    In [823]: from itertools import combinations 
    
    In [824]: df = pd.DataFrame({'Col1': [['Green','Red','Purple'], ['Red', 'Yellow', 'Blue'], ['Brown', 'Green', 'Yellow', 'Blue']]}, index=['A', 
        ...: 'B', 'C']) 
    
    In [827]: df['Col1'] = df.Col1.apply(lambda x: set(x)) 
    
    In [828]: df 
    Out[828]: 
              Col1 
    A   {Purple, Red, Green} 
    B   {Red, Blue, Yellow} 
    C {Green, Yellow, Blue, Brown} 
    

    各リストはCol1にしています効率的に組合を見つけるための集合に変換されました。 、今

    In [845]: df1 = pd.DataFrame(data=list(combinations(df.index.tolist(), 2)), columns=['Src', 'Dst']) 
    
    In [849]: df1 
    Out[849]: 
        Src Dst 
    0 A B 
    1 A C 
    2 B C 
    

    和集合を取ると、その長さを見つけるための機能を適用します。次に、我々はdf内のすべての行の対の組み合わせを作成するためにitertools.combinationsを使用します。 SrcDstの列は、dfのルックアップとして機能します。

    In [859]: df1['Weights'] = df1.apply(lambda x: len(df.loc[x['Src']]['Col1'].intersection(df.loc[x['Dst']]['Col1'])), axis=1) 
    
    In [860]: df1 
    Out[860]: 
        Src Dst Weights 
    0 A B  1 
    1 A C  1 
    2 B C  2 
    

    私は最初のアドバイス設定変換を行います。毎回あなたのリストをセットに変換するのは、費用がかかり、無駄です。より高速化のために

    、おそらくもにしたいと思います@Wenを行っているとして常にdf.locを呼び出すとノッチそれが遅くなりますので、新しいデータフレーム内の2つの列にセットをコピーします。

    +0

    私は同じ方法を使用していると思いますが、あなたはより良いupvoteです〜 – Wen

    +0

    @Wen申し訳ありません!私はあなたのものとは無関係に私の答えを書いた。若干の微妙な違いがありますが、多くの点で似ています。私はあなたも+1に値すると信じています:) –

    3

    これを試してください。それほどきちんとしていませんが、仕事。 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 
    
    1
    • セット
    • の配列を取得ペアワイズ交差を取得し、理解

    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 
    
    関連する問題