Ich habe einen CSV von 7 Millionen Biodiversitätsdatensätzen, in denen Taxonomiestufen als Spalten angegeben sind. Zum Beispiel:
RecordID,kingdom,phylum,class,order,family,genus,species
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Homo,Homo sapiens
2,Animalia,Chordata,Mammalia,Carnivora,Canidae,Canis,Canis
3,Plantae,nan,Magnoliopsida,Brassicales,Brassicaceae,Arabidopsis,Arabidopsis thaliana
4,Plantae,nan,Magnoliopsida,Fabales,Fabaceae,Phaseoulus,Phaseolus vulgaris
Ich möchte eine Visualisierung in D3 erstellen, aber das Datenformat muss ein Netzwerk sein, in dem jeder unterschiedliche Wert der Spalte für einen bestimmten Wert ein untergeordnetes Element der vorherigen Spalte ist. Ich muss von der CSV zu so etwas wechseln:
{
name: 'Animalia',
children: [{
name: 'Chordata',
children: [{
name: 'Mammalia',
children: [{
name: 'Primates',
children: 'Hominidae'
}, {
name: 'Carnivora',
children: 'Canidae'
}]
}]
}]
}
Ich habe keine Idee, wie man das macht, ohne tausend for-Schleifen zu verwenden. Hat jemand einen Vorschlag, wie man dieses Netzwerk entweder mit Python oder Javascript erstellt?
javascript
python
d3.js
data-visualization
hierarchical-data
Andres Camilo Zuñiga Gonzalez
quelle
quelle
nan
für das Phylum enthaltende Magnoliopsida. Was ist dasnan
? Das Phylum ist Anthophyta oder alternativ Magnolie (es ist das alte Phylum Angiospermae).Antworten:
Zum Erstellen des gewünschten genau verschachtelten Objekts verwenden wir eine Mischung aus reinem JavaScript und einer D3-Methode mit dem Namen
d3.stratify
. Beachten Sie jedoch, dass 7 Millionen Zeilen (siehe Post-Scriptum unten) viel zu berechnen sind.Es ist sehr wichtig zu erwähnen, dass Sie für diese vorgeschlagene Lösung die Königreiche in verschiedene Datenfelder trennen müssen (z. B. mithilfe von
Array.prototype.filter
). Diese Einschränkung tritt auf, weil wir einen Wurzelknoten benötigen und in der linnäischen Taxonomie keine Beziehung zwischen Königreichen besteht (es sei denn, Sie erstellen "Domäne" als obersten Rang, der die Wurzel für alle Eukaryoten ist, aber dann haben Sie dieselbe Problem für Archaea und Bakterien).Angenommen, Sie haben diese CSV (ich habe einige weitere Zeilen hinzugefügt) mit nur einem Königreich:
Basierend auf dieser CSV erstellen wir hier ein Array mit dem Namen,
tableOfRelationships
das, wie der Name schon sagt, die Beziehungen zwischen den Rängen aufweist:Für die obigen Daten ist dies
tableOfRelationships
:Schauen Sie sich
null
als übergeordnetes Element Folgendes anAnimalia
: Deshalb habe ich Ihnen gesagt, dass Sie Ihren Datensatz nach Königreichen trennen müssen. Es kann nur einennull
Wert in der gesamten Tabelle geben.Basierend auf dieser Tabelle erstellen wir schließlich die Hierarchie mit
d3.stratify()
:Und hier ist die Demo. Öffnen Sie die Konsole Ihres Browsers (die des Snippets ist für diese Aufgabe nicht sehr gut geeignet) und überprüfen Sie die verschiedenen Ebenen (
children
) des Objekts:Code-Snippet anzeigen
PS : Ich weiß nicht, welche Art von Daten Sie erstellen werden, aber Sie sollten taxonomische Ränge wirklich vermeiden. Die gesamte linnäische Taxonomie ist veraltet, wir verwenden keine Ränge mehr: Da die phylogenetische Systematik Mitte der 60er Jahre entwickelt wurde, verwenden wir nur Taxa ohne taxonomischen Rang (Lehrer für Evolutionsbiologie hier). Ich bin auch ziemlich neugierig auf diese 7 Millionen Reihen, da wir etwas mehr als 1 Million Arten beschrieben haben!
quelle
Mit Python und
python-benedict
Library ist es einfach, genau das zu tun, was Sie brauchen (es ist Open Source auf Github :Installation
pip install python-benedict
Die erste Druckausgabe ist:
Die zweite gedruckte Ausgabe ist:
quelle
quelle
Dies scheint unkompliziert zu sein. Vielleicht verstehe ich Ihr Problem nicht.
Die gewünschte Datenstruktur besteht aus einem verschachtelten Satz von Wörterbüchern, Schlüssel / Wert-Paaren. Ihr Königreichswörterbuch der obersten Ebene enthält einen Schlüssel für jedes Ihrer Königreiche, dessen Werte Phylum-Wörterbücher sind. Ein Phylum-Wörterbuch (für ein Königreich) hat einen Schlüssel für jeden Phylum-Namen und jeder Schlüssel hat einen Wert, der ein Klassenwörterbuch ist, und so weiter.
Um das Codieren zu vereinfachen, haben Ihre Gattungswörterbücher einen Schlüssel für jede Art, aber die Werte für die Art sind leere Wörterbücher.
Dies sollte das sein, was Sie wollen; Keine seltsamen Bibliotheken erforderlich.
Zum Testen habe ich Ihre Daten und
pprint
aus der Standardbibliothek verwendet.bekommen
Wenn Sie Ihre Frage noch einmal lesen, möchten Sie möglicherweise eine große Tabelle mit Paaren ('Link von einer allgemeineren Gruppe', 'Link zu einer spezifischeren Gruppe'). Das heißt, "Animalia" -Links zu "Animalia: Chordata" und "Animalia: Chordata" -Links zu "Animalia: Chordata: Mammalia" usw. Leider bedeutet das "Nan" in Ihren Daten, dass Sie bei jedem Link vollständige Namen benötigen. If ( Eltern, Kind) Paare sind das, was Sie wollen. Gehen Sie den Baum folgendermaßen:
Geben:
quelle
name
undchildren
wie in der Frage angefordert zurück.In Python besteht eine Möglichkeit zum Codieren eines Baums darin, a zu verwenden
dict
, wobei die Schlüssel Knoten darstellen und der zugehörige Wert das übergeordnete Element des Knotens ist:Dies hat den Vorteil, dass Sie sicherstellen, dass die Knoten eindeutig sind, da
dicts
keine doppelten Schlüssel vorhanden sein können.Wenn Sie stattdessen einen allgemeineren gerichteten Graphen codieren möchten (dh Knoten können mehr als ein übergeordnetes Element haben), können Sie Listen für Werte verwenden und die Kinder (oder Eltern, nehme ich an) darstellen:
Sie können mit Objekten in JS etwas Ähnliches tun und bei Bedarf Listen durch Arrays ersetzen.
Hier ist der Python-Code, mit dem ich das erste Diktat oben erstellt habe:
quelle
Wahrscheinlich der einfachste Weg , um Ihre Daten in eine Hierarchie dreht die Nutzung von D3-interner Verschachtelung Betreiber
d3.nest()
:Durch die Registrierung von Schlüsselfunktionen über können
nest.key()
Sie einfach die Struktur Ihrer Hierarchie festlegen. Ähnlich wie Gerardo in seiner Antwort dargelegt hat, können Sie die.columns
im Datenarray nach dem Parsen Ihrer CSV bereitgestellte Eigenschaft verwenden, um die Generierung dieser Schlüsselfunktionen zu automatisieren. Der gesamte Code besteht aus folgenden Zeilen:Beachten Sie jedoch, dass die resultierende Hierarchie nicht genau der in Ihrer Frage angeforderten Struktur ähnelt, da die Objekte
{ key, values }
stattdessen sind{ name, children }
. Dies gilt übrigens auch für Gerardos Antwort. Dies gilt nicht für beide Antworten verletzt, obwohl, wie die Ergebnisse können durch lastet werdend3.hierarchy()
durch eine Angabe Kinder Accessor - Funktion:Die folgende Demo fügt alle Teile zusammen:
Code-Snippet anzeigen
Vielleicht möchten Sie auch einen Blick auf die Konvertierung von Schlüsseln und Werten von d3.nest () in Namen und untergeordnete Elemente werfen, falls Sie das Gefühl haben, genau Ihre veröffentlichte Struktur zu haben.
quelle
d3.nest
solange es dauert: Es wird bald veraltet sein.Eine lustige Herausforderung. Versuchen Sie diesen Javascript-Code. Der Einfachheit halber benutze ich Lodashs Set.
Dies ergibt das Endergebnis (ähnlich) wie gewünscht.
quelle
In der Tat ist @Charles Merriam seine Lösung sehr elegant.
Wenn Sie ein Ergebnis erzielen möchten, das mit der Frage übereinstimmt, versuchen Sie Folgendes.
quelle