2017-09-27 6 views
1

J'ai une dfGénération d'une matrice de similarité de pandas géants dataframe

id val1 val2 val3 
100 aa  bb  cc 
200 bb  cc  0 
300 aa  cc  0 
400 bb  aa  cc 

De cela, je dois générer une df, quelque chose comme ceci:

 100 200 300 400      
100 3 2 2 3 
200 2 2 1 2 
300 2 1 2 2 
400 3 2 2 3 

Explaination: id 100 contient aa,bb,cc et contient

Il ya 2 similar valeurs.

Par conséquent, dans ma matrice finale, la cellule d'intersection index 100 et colonne 200, doit être inséré.

De même pour id 200- valeurs sont bb,cc,0 et que pour id 300 - aa,cc,0

Ici, la similitude est donc dans ma matrice finale la cellule correspondant à 200 (indice) -300 (colonne) doit être inséré avec 1.

Répondre

2

Certains prétraitement. Tout d'abord, set_index à id et se débarrasser de 0 s, nous n'en avons pas besoin.

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 

Maintenant, utilisez une combinaison de pd.get_dummies et df.dot et obtenir vos scores de similarité.

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 
+0

Je pense que les zéros doivent être traités comme toute autre valeur. Notez que votre sortie est un peu différente – AndreyF

+0

@AndreyF De ceci j'ai compris: 'De même pour l'identification 200 - les valeurs sont bb, cc, 0 et que pour l'identificateur 300 - aa, cc, 0; Ici la similitude est 1' que les 0 ne devraient pas être comptés –

+0

@jezrael J'ai essayé cela ... cela me donne une réponse incorrecte pour les autres colonnes. –

1

vous pouvez convertir les données en ensembles et les l'intersection avec:

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) 

La sortie désirée sera:

 100 200 300 400 
100 3 2 2 3 
200 2 2 1 2 
300 2 1 2 2 
400 3 2 2 3 
+1

Dans votre réponse, les 0 sont comptés, donc 200-300 est 2, quand il devrait être 1. La sortie de OP est clairement incohérente. –

+0

corrigé. Maintenant, je laisse tomber les valeurs '0' – AndreyF