Réordonner les éléments de matrice afin de refléter la colonne et le regroupement de lignes en python naiive

StackOverflow https://stackoverflow.com/questions/2455761

Question

Je cherche un moyen d'effectuer le regroupement séparément sur les lignes de la matrice et que sur ses colonnes, réorganisez les données dans la matrice pour refléter le regroupement et mettre tous ensemble. Le problème de clustering est facilement résoluble, est donc la création de dendrogramme (par exemple dans ce blog ou " Programmation intelligence collective »). Cependant, comment réorganiser les données ne sait pas pour moi.

Finalement, je suis à la recherche d'un moyen de créer des graphiques similaires à celui-ci en utilisant Python naïf (avec une bibliothèque « standard » tels que numpy, matplotlib etc, mais sans en utilisant R ou d'autres outils externes).


(source: warwick. ac.uk)

Clarifications

On m'a demandé ce que je voulais dire par réordonnancement. Lorsque vous données de cluster dans une matrice d'abord par des lignes de la matrice, puis par ses colonnes, chaque cellule de la matrice peut être identifiée par la position dans les deux dendrogrammes. Si vous réorganisez les lignes et les colonnes de la matrice originale de telle sorte que les éléments qui sont proches chacun à l'autre dans les dendrogrammes se rapprochent chacun à l'autre dans la matrice, puis générer heatmap, le regroupement des données peut devenir évident pour le spectateur (comme dans la figure ci-dessus)

Était-ce utile?

La solution

Voir mon réponse récente , copié en partie ci-dessous, cette question connexe.

import scipy
import pylab
import scipy.cluster.hierarchy as sch

# Generate features and distance matrix.
x = scipy.rand(40)
D = scipy.zeros([40,40])
for i in range(40):
    for j in range(40):
        D[i,j] = abs(x[i] - x[j])

# Compute and plot dendrogram.
fig = pylab.figure()
axdendro = fig.add_axes([0.09,0.1,0.2,0.8])
Y = sch.linkage(D, method='centroid')
Z = sch.dendrogram(Y, orientation='right')
axdendro.set_xticks([])
axdendro.set_yticks([])

# Plot distance matrix.
axmatrix = fig.add_axes([0.3,0.1,0.6,0.8])
index = Z['leaves']
D = D[index,:]
D = D[:,index]
im = axmatrix.matshow(D, aspect='auto', origin='lower')
axmatrix.set_xticks([])
axmatrix.set_yticks([])

# Plot colorbar.
axcolor = fig.add_axes([0.91,0.1,0.02,0.8])
pylab.colorbar(im, cax=axcolor)

# Display and save figure.
fig.show()
fig.savefig('dendrogram.png')


(source: stevetjoa.com )

Autres conseils

Je ne suis pas sûr de comprendre complètement, mais il semble que vous essayez de réindexer chaque axe du tableau en fonction des sortes des indicies de dendrogramme. Je suppose que cela suppose, il y a une certaine logique comparative dans chaque délimitation de branche. Si tel est le cas, alors cela fonctionnerait (?):

>>> x_idxs = [(0,1,0,0),(0,1,1,1),(0,1,1),(0,0,1),(1,1,1,1),(0,0,0,0)]
>>> y_idxs = [(1,1),(0,1),(1,0),(0,0)]
>>> a = np.random.random((len(x_idxs),len(y_idxs)))
>>> x_idxs2, xi = zip(*sorted(zip(x_idxs,range(len(x_idxs)))))
>>> y_idxs2, yi = zip(*sorted(zip(y_idxs,range(len(y_idxs)))))
>>> a2 = a[xi,:][:,yi]

x_idxs et y_idxs sont les indicies de dendrogramme. a est la matrice non triés. xi et yi sont votre nouvelle matrice ligne / colonne indicies. a2 est la matrice triée en x_idxs2 et y_idxs2 sont les nouvelles, triées indicies de dendrogramme. Cela suppose que, lorsque le dendrogramme a été créé qu'une colonne branche 0 / ligne est toujours relativement plus grande / plus petite qu'une branche 1.

Si votre y_idxs et x_idxs ne sont pas des listes mais sont des tableaux numpy, vous pouvez utiliser np.argsort de manière similaire.

Je sais que cela est très tard pour le jeu, mais j'ai fait un objet tracé basé sur le code du poste sur cette page. Il est enregistré sur pip, afin de vous installer suffit d'appeler

pip install pydendroheatmap

consultez la page GitHub du projet ici: https://github.com/themantalope/pydendroheatmap

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top