Mam csv 7 milionów rekordów różnorodności biologicznej, w których poziomy taksonomii są w kolumnach. Na przykład:
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
Chcę utworzyć wizualizację w D3, ale formatem danych musi być sieć, w której każda inna wartość kolumny jest potomkiem poprzedniej kolumny dla określonej wartości. Muszę przejść z csv do czegoś takiego:
{
name: 'Animalia',
children: [{
name: 'Chordata',
children: [{
name: 'Mammalia',
children: [{
name: 'Primates',
children: 'Hominidae'
}, {
name: 'Carnivora',
children: 'Canidae'
}]
}]
}]
}
Nie wpadłem na pomysł, jak to zrobić bez użycia tysiąca pętli. Czy ktoś ma sugestie, jak utworzyć tę sieć w Pythonie lub javascript?
javascript
python
d3.js
data-visualization
hierarchical-data
Andres Camilo Zuñiga Gonzalez
źródło
źródło
nan
dla Phylum zawierającego Magnoliopsida. Co tonan
jest Phylum to Anthophyta lub alternatywnie Magnolia (to stara Phylum Angiospermae).Odpowiedzi:
Do utworzenia dokładnie zagnieżdżonego obiektu, którego chcesz, użyjemy kombinacji czystego JavaScript i metody D3 o nazwie
d3.stratify
. Należy jednak pamiętać, że 7 milionów wierszy (patrz poniżej post scriptum ) to dużo do obliczenia.Bardzo ważne jest, aby wspomnieć, że w tym proponowanym rozwiązaniu będziesz musiał rozdzielić Królestwa na różne tablice danych (na przykład przy użyciu
Array.prototype.filter
). To ograniczenie występuje, ponieważ potrzebujemy węzła głównego, a w taksonomii linnańskiej nie ma związku między Królestwami (chyba że stworzysz „domenę” jako najwyższą rangę, która będzie pierwiastkiem dla wszystkich eukariontów, ale wtedy będziesz mieć to samo problem dla Archaea i Bakterii).Załóżmy, że masz ten plik CSV (dodałem kilka wierszy) tylko z jednym Królestwem:
Na podstawie tego pliku CSV utworzymy tutaj tablicę o nazwie,
tableOfRelationships
która, jak sama nazwa wskazuje, ma relacje między szeregami:Dla powyższych danych jest to
tableOfRelationships
:Spójrz na
null
rodzicaAnimalia
: dlatego powiedziałem ci, że musisz oddzielić zestaw danych od Kingdoms,null
w całej tabeli może być tylko jedna wartość.Wreszcie, na podstawie tej tabeli, tworzymy hierarchię przy użyciu
d3.stratify()
:A oto wersja demo. Otwórz konsolę przeglądarki (fragment kodu nie jest zbyt dobry do tego zadania) i sprawdź kilka poziomów (
children
) obiektu:Pokaż fragment kodu
PS : Nie wiem, jaki rodzaj danych stworzysz, ale naprawdę powinieneś unikać rang taksonomicznych. Cała taksonomia linnańska jest przestarzała, nie używamy już szeregów: ponieważ systematyka filogenetyczna została opracowana w połowie lat 60-tych, używamy tylko taksonów, bez żadnej rangi taksonomicznej (tutaj nauczyciel biologii ewolucyjnej). Jestem też bardzo ciekawy tych 7 milionów wierszy, ponieważ opisaliśmy nieco ponad 1 milion gatunków!
źródło
Łatwo jest robić dokładnie to, czego potrzebujesz, używając Pythona i
python-benedict
biblioteki (jest to oprogramowanie typu open source w Github :Instalacja
pip install python-benedict
Pierwszym wyjściem będzie:
Drugim wydrukiem będą:
źródło
źródło
Wydaje się to proste, więc może nie rozumiem twojego problemu.
Potrzebna struktura danych to zagnieżdżony zestaw słowników, pary klucz / wartość. Twój słownik królestwa najwyższego poziomu ma klucz do każdego z twoich królestw, których wartościami są słowniki typów. Słownik typu (dla jednego królestwa) ma klucz dla każdej nazwy typu, a każdy klucz ma wartość, która jest słownikiem klas i tak dalej.
Aby ułatwić kodowanie, słowniki rodzajów będą miały klucz dla każdego gatunku, ale wartości dla gatunku będą pustymi słownikami.
To powinno być to, czego chcesz; nie są wymagane dziwne biblioteki.
Aby to przetestować, wykorzystałem twoje dane i
pprint
ze standardowej biblioteki.coraz
Czytając ponownie twoje pytanie, możesz chcieć mieć duży zestaw par („link z bardziej ogólnej grupy”, „link do bardziej szczegółowej grupy”). Oznacza to, że „Animalia” prowadzi do „Animalia: Chordata” i „Animalia: Chordata” prowadzi do „Animalia: Chordata: Mammalia” itd. Niestety, „nan” w Twoich danych oznacza, że potrzebujesz pełnych nazwisk przy każdym linku. pary rodzic, dziecko) są tym, czego chcesz, idź po drzewie w ten sposób:
dający:
źródło
name
ichildren
na żądanie w pytaniu.W Pythonie jednym ze sposobów kodowania drzewa jest użycie znaku
dict
, w którym klucze reprezentują węzły, a powiązaną wartością jest element nadrzędny węzła:Zaletą tego jest upewnienie się, że węzły są unikalne, ponieważ
dicts
nie mogą mieć zduplikowanych kluczy.Jeśli zamiast tego chcesz zakodować bardziej ogólny wykres (tzn. Węzły mogą mieć więcej niż jednego rodzica), możesz użyć list do wartości i mieć reprezentujące dzieci (lub rodziców, jak sądzę):
Możesz zrobić coś podobnego z Obiektami w JS, zastępując tablice listami, jeśli to konieczne.
Oto kod Pythona, którego użyłem do stworzenia pierwszego powyższego dykta:
źródło
Prawdopodobnie najprostszym sposobem przekształcenia danych w hierarchię jest użycie wbudowanego operatora zagnieżdżania D3
d3.nest()
:Rejestrując kluczowe funkcje za pośrednictwem
nest.key()
, możesz łatwo określić strukturę swojej hierarchii. Podobnie jak Gerardo w swojej odpowiedzi , możesz użyć.columns
właściwości ujawnionej w tablicy danych po przeanalizowaniu pliku CSV, aby zautomatyzować generowanie tych kluczowych funkcji. Cały kod sprowadza się do następujących wierszy:Zauważ jednak, że wynikowa hierarchia nie do końca przypomina strukturę wymaganą w pytaniu, ponieważ obiekty są
{ key, values }
zamiast{ name, children }
; tak przy okazji, to samo dotyczy odpowiedzi Gerardo. Nie ma to jednak negatywnego wpływu na obie odpowiedzi, ponieważ wyniki mogą być przeciążoned3.hierarchy()
przez określenie funkcji akcesora podrzędnego:Poniższe demo łączy wszystkie części razem:
Pokaż fragment kodu
Możesz także rzucić okiem na klucz d3.nest () i konwersję wartości na imię i dzieci, na wypadek, gdybyś poczuł potrzebę posiadania dokładnie takiej struktury.
źródło
d3.nest
dopóki trwa: wkrótce zostanie wycofany.Zabawne wyzwanie. Wypróbuj ten kod javascript. Używam zestawu Lodasha dla uproszczenia.
To daje wynik końcowy (podobny) do tego, czego chcesz.
źródło
W rzeczywistości @Charles Merriam jego rozwiązanie jest bardzo eleganckie.
Jeśli chcesz uzyskać wynik identyczny z pytaniem, spróbuj wykonać następujące czynności.
źródło