Eu tenho um CSV de 7 milhões de registros de biodiversidade, onde os níveis de taxonomia são como colunas. Por exemplo:
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
Quero criar uma visualização no D3, mas o formato dos dados deve ser uma rede, onde cada valor diferente da coluna é filho da coluna anterior para um determinado valor. Eu preciso ir do csv para algo como isto:
{
name: 'Animalia',
children: [{
name: 'Chordata',
children: [{
name: 'Mammalia',
children: [{
name: 'Primates',
children: 'Hominidae'
}, {
name: 'Carnivora',
children: 'Canidae'
}]
}]
}]
}
Eu não tive uma idéia de como fazer isso sem usar mil para loops. Alguém tem uma sugestão sobre como criar esta rede em python ou javascript?
javascript
python
d3.js
data-visualization
hierarchical-data
Andres Camilo Gonzalez, Zuñiga
fonte
fonte
nan
para o Phylum contendo Magnoliopsida. O que é issonan
? O filo é Anthophyta, ou alternativamente Magnólia (é o antigo Phylum Angiospermae).Respostas:
Para criar o objeto aninhado exato desejado, usaremos uma mistura de JavaScript puro e um método D3 chamado
d3.stratify
. No entanto, tenha em mente que 7 milhões de linhas (consulte o post scriptum abaixo) são muito para calcular.É muito importante mencionar que, para esta solução proposta, você precisará separar os Reinos em diferentes matrizes de dados (por exemplo, usando
Array.prototype.filter
). Essa restrição ocorre porque precisamos de um nó raiz e, na taxonomia de Linna, não há relação entre reinos (a menos que você crie "Domínio" como uma classificação superior, que será a raiz de todos os eucariotos, mas você terá o mesmo problema para arquéias e bactérias).Então, suponha que você tenha esse CSV (adicionei mais algumas linhas) com apenas um reino:
Com base nesse CSV, criaremos uma matriz aqui chamada
tableOfRelationships
que, como o nome indica, possui os relacionamentos entre as fileiras:Para os dados acima, este é o
tableOfRelationships
:Dê uma olhada em
null
como paiAnimalia
: foi por isso que eu lhe disse que você precisa separar seu conjunto de dados por reinos; só pode haver umnull
valor em toda a tabela.Por fim, com base nessa tabela, criamos a hierarquia usando
d3.stratify()
:E aqui está a demonstração. Abra o console do navegador (o do snippet não é muito bom para esta tarefa) e inspecione os vários níveis (
children
) do objeto:Mostrar snippet de código
PS : Não sei que tipo de dados você criará, mas deve evitar filas taxonômicas. Toda a taxonomia linnaeana está desatualizada, não usamos mais fileiras: como a sistemática filogenética foi desenvolvida em meados dos anos 60, usamos apenas táxons, sem nenhuma classificação taxonômica (professor de biologia evolutiva aqui). Além disso, estou bastante curioso sobre esses 7 milhões de linhas, pois descrevemos pouco mais de 1 milhão de espécies!
fonte
É fácil fazer exatamente o que você precisa usando python e
python-benedict
library (é de código aberto no Github :Instalação
pip install python-benedict
A primeira saída de impressão será:
A segunda saída impressa será:
fonte
fonte
Parece simples, então talvez eu não esteja entendendo o seu problema.
A estrutura de dados que você deseja é um conjunto aninhado de dicionários, pares de chave / valor. Seu dicionário de reino de nível superior tem uma chave para cada um de seus reinos, cujos valores são dicionários de filo. Um dicionário de filo (para um reino) tem uma chave para cada nome de filo e cada chave tem um valor que é um dicionário de classe e assim por diante.
Para simplificar o código, seus dicionários de gênero terão uma chave para cada espécie, mas os valores para as espécies serão dicionários vazios.
Isso deve ser o que você deseja; nenhuma biblioteca estranha é necessária.
Para testá-lo, usei seus dados e
pprint
da biblioteca padrão.obtendo
Lendo sua pergunta novamente, você pode querer uma grande tabela de pares ('link de um grupo mais geral', 'link para um grupo mais específico'). Ou seja, 'Animalia' vincula-se a 'Animalia: Chordata' e 'Animalia: Chordata' a 'Animalia: Chordata: Mammalia "etc. Infelizmente, o' nan 'em seus dados significa que você precisa de nomes completos em cada link. Se ( pares pai, filho) são o que você deseja, ande na árvore desta maneira:
dando:
fonte
name
echildren
conforme solicitado na pergunta.No Python, uma maneira de codificar uma árvore é usar a
dict
, onde as chaves representam nós e o valor associado é o pai do nó:Uma vantagem disso é que você garante que os nós sejam exclusivos, pois
dicts
não podem ter chaves duplicadas.Se você deseja codificar um gráfico direcionado mais geral (ou seja, os nós podem ter mais de um pai), use listas para valores e faça com que representem filhos (ou pais, suponho):
Você poderia fazer algo semelhante com Objetos em JS, substituindo Arrays por listas, se necessário.
Aqui está o código Python que eu usei para criar o primeiro ditado acima:
fonte
Provavelmente, a maneira mais simples de transformar seus dados em uma hierarquia é usar o operador de aninhamento interno do D3
d3.nest()
:Ao registrar as funções principais via,
nest.key()
você pode especificar facilmente a estrutura da sua hierarquia. Assim como Gerardo disposto em sua resposta, você pode usar a.columns
propriedade exposta na matriz de dados após analisar seu CSV para automatizar a geração dessas funções principais. O código inteiro se resume às seguintes linhas:Note, no entanto, que a hierarquia resultante não exatamente se assemelham a estrutura solicitada na sua pergunta como os objetos são
{ key, values }
, em vez de{ name, children }
; a propósito, isso também se aplica à resposta de Gerardo. Isso não é prejudicial para as duas respostas, no entanto, como os resultados podem ser congestionadosd3.hierarchy()
, especificando uma função de acessador secundário:A seguinte demonstração reúne todas as partes:
Mostrar snippet de código
Você também pode dar uma olhada na conversão de chave e valores d3.nest () para nome e filhos , caso sinta a necessidade de ter exatamente sua estrutura postada.
fonte
d3.nest
enquanto durar: será preterido em breve.Um desafio divertido. Experimente este código javascript. Eu uso o conjunto de Lodash para simplificar.
Isso produz o resultado final (semelhante) ao que você deseja.
fonte
De fato, @Charles Merriam, sua solução é muito elegante.
Se você deseja obter um resultado igual ao da pergunta, tente o seguinte.
fonte