найти переходную связь между двумя колоннами в пандах - PullRequest
0 голосов
/ 07 июня 2018

У меня есть кадр данных pandas с 2 столбцами - user1 и user2 что-то вроде этого

Теперь я хочу сделать транзитивное отношение, такое, что если A связано с B и Bдля C и C для D, тогда я хочу вывод в виде списка, например "ABCD" в одной группе и "EFG" в другой группе.

Спасибо

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Если вы хотите найти все переходные отношения, то, скорее всего, вам нужно выполнить рекурсию.Возможно, следующий фрагмент кода может помочь:

import pandas as pd
data={'user1':['A','A','B', 'C', 'E', 'F'],
      'user2':['B', 'C','C','D','F','G']}
df=pd.DataFrame(data)

print(df)

# this method is similar to the commnon table expression (CTE) in SQL                                                                    
def cte(df_anchor,df_ref,level):
    if (level==0):
        df_anchor.insert(0, 'user_root',df_anchor['user1'])
        df_anchor['level']=0
        df_anchor['relationship']=df_anchor['user1']+'-'+df_anchor['user2']
        _df_anchor=df_anchor
    if (level>0):
        _df_anchor=df_anchor[df_anchor.level==level]
    _df=pd.merge(_df_anchor, df_ref , left_on='user2', right_on='user1', how='inner', suffixes=('', '_x'))

    if not(_df.empty):
        _df['relationship']=_df['relationship']+'-'+_df['user2_x']
        _df['level']=_df['level']+1
        _df=_df[['user_root','user1_x', 'user2_x', 'level','relationship']].rename(columns={'user1_x': 'user1', 'user2_x': 'user2'})
        df_anchor_new=pd.concat([df_anchor, _df])
        return cte(df_anchor_new, df_ref, level+1)
    else:
        return df_anchor

df_rel=cte(df, df, 0)
print("\nall relationship=\n",df_rel)

print("\nall relationship related to A=\n", df_rel[df_rel.user_root=='A'])

 user1 user2
0     A     B
1     A     C
2     B     C
3     C     D
4     E     F
5     F     G

all relationship=
   user_root user1 user2  level relationship
0         A     A     B      0          A-B
1         A     A     C      0          A-C
2         B     B     C      0          B-C
3         C     C     D      0          C-D
4         E     E     F      0          E-F
5         F     F     G      0          F-G
0         A     B     C      1        A-B-C
1         A     C     D      1        A-C-D
2         B     C     D      1        B-C-D
3         E     F     G      1        E-F-G
0         A     C     D      2      A-B-C-D

all relationship related to A=
   user_root user1 user2  level relationship
0         A     A     B      0          A-B
1         A     A     C      0          A-C
0         A     B     C      1        A-B-C
1         A     C     D      1        A-C-D
0         A     C     D      2      A-B-C-D
0 голосов
/ 07 июня 2018

Если у вас есть только 2 группы, вы можете сделать это таким образом.Но это работает только для 2 групп, и вы не можете обобщить:

x = []
y = []
x.append(df['user1'][0])
x.append(df['user2'][0])

for index, i in enumerate(df['user1']):
    if df['user1'][index] in x:
        x.append(df['user2'][index])
    else:
        y.append(df['user1'][index])
        y.append(df['user2'][index])
x = set(x)
y = set(y)
...