1

我有一个 Pandas 数据框,其中包含三列id(唯一标识符),然后是三个字符串列event_oneevent_twoevent_three,如下所示:

test_df.head()

    id  event_one  event_two  event_three
0   N1  'aaa'      'abc'      'xyz'
1   N2  'bbb'      'abc'      'uvw'
2   N3  'ccc'      'def'      'xyz'
3   N4  'aaa'      'def'      'uvw'
4   N5  'aaa'      'abc'      'zzz'

我想创建一个邻接矩阵(作为数据框),对于所有 ID 对,它将测试每个事件列中的字符串相等性,然后计算事件总数中匹配的事件的比例。

例如,如果我们与 进行比较N1N5则该对的邻接矩阵中的相关条目将为 2/3(或 0.66..),因为它们匹配event_oneevent_two,但不匹配event_three

使用test_df上面的示例,最终的邻接矩阵(表示为 Pandas 数据框)如下所示:

      N1    N2    N3    N4    N5
      ----------------------------
N1|   -     1/3   1/3   1/3   2/3
N2|   1/3   -     0     1/3   1/3
N3|   1/3   0     -     1/3   0
N4|   1/3   1/3   1/3   -     1/3
N5|   2/3   1/3   0     1/3   -

到目前为止,我编写的代码(见下文)使用pdist和 lambda 表达式,但仅基于event_one。如何将其扩展到所有三个事件列,然后计算最终计算,或者有更好的方法吗?

import pandas as pd
from scipy.spatial.distance import pdist, squareform

# Create the example dataframe
events = {'id': ['N1', 'N2', 'N3', 'N4', 'N5'], 
          'event_one': ['aaa', 'bbb', 'ccc', 'aaa', 'aaa'],
          'event_two': ['abc', 'abc', 'def', 'def', 'abc'],
          'event_three': ['xyz', 'uvw', 'xyz', 'uvw', 'zzz']}
df = pd.DataFrame(events, columns=['id', 'event_one', 'event_two', 'event_three'])

# Create an adjacency matrix by comparing event_one using pdist

index_ndarray = df['id'].values
event_one_series = df['event_one']
dm = pdist(event_one_series[:, None], lambda u, v: 1 if u == v else 0)
event_one_matrix_df = pd.DataFrame(
    squareform(dm),
    dtype='str',
    index=index_ndarray,
    columns=index_ndarray)
event_one_matrix_df

    N1      N2      N3      N4      N5
N1  0.0     0.0     0.0     1.0     1.0
N2  0.0     0.0     0.0     0.0     0.0
N3  0.0     0.0     0.0     0.0     0.0
N4  1.0     0.0     0.0     0.0     1.0
N5  1.0     0.0     0.0     1.0     0.0

任何建议都会很棒,谢谢。

4

1 回答 1

2

让我们使用filter来选择event类似的列,然后使用pdist并传递一个自定义 lambda 函数,该函数f比较成对的行并返回匹配的事件的分数:

from scipy.spatial.distance import pdist, squareform

f = lambda u, v: (u == v).sum() / len(u)
a = squareform(pdist(df.filter(like='event'), f))
d = pd.DataFrame(a, index=df['id'].tolist(), columns=df['id'].tolist())

print(d)
         N1        N2        N3        N4        N5
N1  0.000000  0.333333  0.333333  0.333333  0.666667
N2  0.333333  0.000000  0.000000  0.333333  0.333333
N3  0.333333  0.000000  0.000000  0.333333  0.000000
N4  0.333333  0.333333  0.333333  0.000000  0.333333
N5  0.666667  0.333333  0.000000  0.333333  0.000000
于 2020-10-02T13:33:46.547 回答