python—创建一个对称矩阵来统计关系记录

a64a0gku  于 2021-07-14  发布在  Spark
关注(0)|答案(3)|浏览(315)

我想通过一列来计算所有可能的成对关系的数量( Value )基于另一列( ID ).
Dataframe示例:

ID Value
0   1     A
1   1     A
2   1     A
3   1     B
4   1     C
5   2     B
6   2     C
7   2     C

要生成示例Dataframe:

import pandas as pd
df = pd.DataFrame({'ID'    : {0:  1,  1: 1,   2: 1,   3: 1,   4: 1,   
                              5:  2,  6: 2,   7: 2}, 
                   'Value' : {0: 'A', 1: 'A', 2: 'A', 3: 'B', 4: 'C',
                              5: 'B', 6: 'C', 7: 'C'} 
                   })

应为以下对象执行成对计数 ID=1 以及 ID=2 .
可能的成对在哪里 ID=1 ```
(A,A), (A,A), (A,B), (A,C),
(A,A), (A,A), (A,B), (A,C),
(A,A), (A,A), (A,B), (A,C),
(B,A), (B,A), (B,A), (B,C),
(C,A), (C,A), (C,A), (C,B),

可能的成对在哪里 `ID=2` ```
(B,C), (B,C)
(C,B), (C,C)
(C,B), (C,C)

预期Dataframe:

A  B  C
A  6  3  3
B  3  0  3
C  3  3  2

我目前得到的(见下文与其他stackoverflow问题的关系):

df = pd.merge(df, df, on='ID')
df = pd.crosstab(df['Value_x'], df['Value_y']).rename_axis(None).rename_axis(None, axis=1)
print (df)

输出错误:

A  B  C
A  9  3  3
B  3  2  3
C  3  3  5

你可能会发现,这个问题主要与钓鱼台方面有关。我假设我必须关注合并端来处理提议的场景。不过,我到目前为止还不能处理:(有什么建议吗?提前谢谢!
相关问题:这个问题有很多相似之处。然而,这个问题可能有点错误的预期。(a,a)=0,(b,b)=0,(c,c)=0的情况应该是0,因为基于该问题,它们在两种情况(id=1或id=2)中都不存在。如果我们想计算出只计算那些条件>ab,ac,ba,bc,ca,cb(从id=1)和bc,cb(从id=2)。另一方面,这里的主要区别是在对角线上。

iswrvxsc

iswrvxsc1#

让我们试试 dot 之后 crosstab ,然后减去自身对~

s = pd.crosstab(df.ID,df.Value)
out = s.T.dot(s)
np.fill_diagonal(out.values, out.values.diagonal() - s.sum())
out
Value  A  B  C
Value         
A      6  3  3
B      3  0  3
C      3  3  2
t5fffqht

t5fffqht2#

你可以用 itertool.permutations 但将其应用于每一组:

from itertools import permutations

out = pd.DataFrame()
for _, g in df.groupby("ID"):
    d = pd.DataFrame(permutations(g["Value"], 2), columns=["x", "y"])
    x = pd.crosstab(d["x"], d["y"]).rename_axis(None).rename_axis(None, axis=1)
    out = out.add(x, fill_value=0)

print(out.astype(int))

印刷品:

A  B  C
A  6  3  3
B  3  0  3
C  3  3  2
w8biq8rn

w8biq8rn3#

如果需要访问排列,还可以在一个帧中构建所有排列,然后获取整个交叉表。

import pandas as pd
from itertools import permutations

df = pd.DataFrame({'ID': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1,
                          5: 2, 6: 2, 7: 2},
                   'Value': {0: 'A', 1: 'A', 2: 'A', 3: 'B', 4: 'C',
                             5: 'B', 6: 'C', 7: 'C'}
                   })

perms = df.groupby('ID')['Value'] \
    .apply(lambda s: pd.DataFrame(permutations(s, 2), columns=['x', 'y']))

new_df = pd.crosstab(perms.x, perms.y) \
    .rename_axis(None, axis=1) \
    .rename_axis(None, axis=0)

# For Display

print(new_df)
print()
print(perms)

输出
新数据框:

A  B  C
A  6  3  3
B  3  0  3
C  3  3  2

烫发:

x  y
ID         
1  0   A  A
   1   A  A
   2   A  B
   3   A  C
   4   A  A
   5   A  A
   6   A  B
   7   A  C
   8   A  A
   9   A  A
   10  A  B
   11  A  C
   12  B  A
   13  B  A
   14  B  A
   15  B  C
   16  C  A
   17  C  A
   18  C  A
   19  C  B
2  0   B  C
   1   B  C
   2   C  B
   3   C  C
   4   C  B
   5   C  C

相关问题