我有一个df
id val1 val2 val3
100 aa bb cc
200 bb cc 0
300 aa cc 0
400 bb aa cc
由此我必须生成一个df,如下所示:
100 200 300 400
100 3 2 2 3
200 2 2 1 2
300 2 1 2 2
400 3 2 2 3
说明: ID 100 包含aa,bb,cc
, 200 包含bb,cc,0
有两个相似的值。
因此,在我的最终矩阵中,应插入 index-100 和列200 , 2 的交叉单元格。
同样, ID 200 - 值为bb,cc,0
, ID为300 - aa,cc,0
这里的相似度 1 ,因此在我的最终矩阵中 应使用 1插入与 200(索引)-300(列)对应的单元格。
答案 0 :(得分:2)
一些预处理。首先,set_index
到id
并摆脱0
,我们不需要它们。
df = df.set_index('id').replace('0', np.nan)
df
val1 val2 val3
id
100 aa bb cc
200 bb cc NaN
300 aa cc NaN
400 bb aa cc
现在,使用pd.get_dummies
和df.dot
的组合来获取相似度得分。
x = pd.get_dummies(df)
y = x.groupby(x.columns.str.split('_').str[1], axis=1).sum()
y.dot(y.T)
100 200 300 400
id
100 3 2 2 3
200 2 2 1 2
300 2 1 2 2
400 3 2 2 3
答案 1 :(得分:1)
您可以将数据转换为集合,然后将它们相交:
df = df.replace('0', np.nan)
c = df.apply(lambda x: set(x.dropna()), axis=1)
df2 = pd.DataFrame([[len(x.intersection(y)) for x in c] for y in c],columns=c.index,index=c.index)
所需的输出将是:
100 200 300 400
100 3 2 2 3
200 2 2 1 2
300 2 1 2 2
400 3 2 2 3