Saya memiliki csv dari 7 juta catatan keanekaragaman hayati di mana tingkat taksonomi adalah sebagai kolom. Contohnya:
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
Saya ingin membuat visualisasi dalam D3, tetapi format data harus berupa jaringan, di mana setiap nilai kolom yang berbeda adalah anak dari kolom sebelumnya untuk nilai tertentu. Saya perlu beralih dari csv ke yang seperti ini:
{
name: 'Animalia',
children: [{
name: 'Chordata',
children: [{
name: 'Mammalia',
children: [{
name: 'Primates',
children: 'Hominidae'
}, {
name: 'Carnivora',
children: 'Canidae'
}]
}]
}]
}
Saya belum datang dengan ide bagaimana melakukan ini tanpa menggunakan seribu untuk loop. Adakah yang punya saran tentang cara membuat jaringan ini baik dengan python atau javascript?
javascript
python
d3.js
data-visualization
hierarchical-data
Andres Camilo Zuñiga Gonzalez
sumber
sumber
nan
untuk sebuah Filum yang mengandung Magnoliopsida. Apa itunan
? Phylum adalah Anthophyta, atau Magnolia (alternatifnya adalah Phylum Angiospermae).Jawaban:
Untuk membuat objek bersarang tepat yang Anda inginkan kami akan menggunakan campuran JavaScript murni dan metode D3 bernama
d3.stratify
. Namun, ingatlah bahwa 7 juta baris (lihat post scriptum di bawah) banyak yang bisa dihitung.Sangat penting untuk menyebutkan bahwa, untuk solusi yang diusulkan ini, Anda harus memisahkan Kingdoms dalam array data yang berbeda (misalnya, menggunakan
Array.prototype.filter
). Pembatasan ini terjadi karena kita memerlukan simpul root, dan dalam taksonomi Linnaean tidak ada hubungan antara Kerajaan (kecuali jika Anda membuat "Domain" sebagai peringkat teratas, yang akan menjadi root untuk semua eukariota, tetapi kemudian Anda akan memiliki yang sama masalah untuk Archaea dan Bakteri).Jadi, misalkan Anda memiliki CSV ini (saya menambahkan beberapa baris lagi) hanya dengan satu Kerajaan:
Berdasarkan CSV itu, kami akan membuat array di sini bernama
tableOfRelationships
yang, seperti namanya, memiliki hubungan antara peringkat:Untuk data di atas, ini adalah
tableOfRelationships
:Lihatlah
null
sebagai induk dariAnimalia
: itu sebabnya saya katakan bahwa Anda perlu memisahkan dataset Anda dengan Kingdoms, hanya ada satunull
nilai di seluruh tabel.Akhirnya, berdasarkan tabel itu, kami membuat hierarki menggunakan
d3.stratify()
:Dan ini adalah demo. Buka konsol peramban Anda (snipet tidak terlalu bagus untuk tugas ini) dan periksa beberapa level (
children
) objek:Tampilkan cuplikan kode
PS : Saya tidak tahu jenis data apa yang akan Anda buat, tetapi Anda benar-benar harus menghindari peringkat taksonomi. Seluruh taksonomi Linnaean sudah usang, kami tidak menggunakan peringkat lagi: karena sistematika filogenetik dikembangkan pada pertengahan 60-an, kami hanya menggunakan taksa, tanpa peringkat taksonomi (guru biologi evolusi di sini). Juga, saya cukup ingin tahu tentang 7 juta baris ini, karena kami telah menggambarkan lebih dari 1 juta spesies!
sumber
Sangat mudah untuk melakukan apa yang Anda butuhkan menggunakan python dan
python-benedict
pustaka (ini open source di Github :Instalasi
pip install python-benedict
Output cetak pertama adalah:
Output cetak kedua adalah:
sumber
sumber
Ini kelihatannya mudah, jadi mungkin saya tidak mengerti masalah Anda.
Struktur data yang Anda inginkan adalah serangkaian kamus, pasangan kunci / nilai. Kamus kerajaan tingkat atas Anda memiliki kunci untuk masing-masing kerajaan Anda, yang nilainya adalah kamus filum. Kamus filum (untuk satu kerajaan) memiliki kunci untuk setiap nama filum dan setiap kunci memiliki nilai yang merupakan kamus kelas, dan sebagainya.
Untuk membuatnya mudah dikodekan, kamus genus Anda akan memiliki kunci untuk setiap spesies, tetapi nilai untuk spesies tersebut adalah kamus kosong.
Ini harus menjadi apa yang Anda inginkan; tidak diperlukan perpustakaan aneh.
Untuk mengujinya, saya menggunakan data Anda dan
pprint
dari perpustakaan standar.mendapatkan
Membaca pertanyaan Anda lagi, Anda mungkin menginginkan tabel besar pasangan ('tautan dari grup yang lebih umum', 'tautan ke grup yang lebih spesifik'). Yaitu, tautan 'Animalia' ke 'Animalia: Chordata' dan 'Animalia: Chordata' tautan ke 'Animalia: Chordata: Mammalia "dll. Sayangnya,' nan 'dalam data Anda berarti Anda memerlukan nama lengkap di setiap tautan. Jika ( orang tua, anak) pasangan adalah apa yang Anda inginkan, berjalan di pohon dengan cara ini:
memberi:
sumber
name
danchildren
seperti yang diminta dalam pertanyaan.Dalam Python, salah satu cara untuk menyandikan pohon adalah dengan menggunakan
dict
, di mana kunci mewakili node dan nilai yang terkait adalah induk simpul:Keuntungan dari hal ini adalah Anda memastikan bahwa node tersebut unik, karena
dicts
tidak dapat memiliki kunci duplikat.Jika Anda ingin menyandikan grafik yang diarahkan lebih umum sebagai gantinya (yaitu, node dapat memiliki lebih dari satu orang tua), Anda dapat menggunakan daftar untuk nilai dan memiliki anak-anak yang mewakili (atau orang tua, saya kira):
Anda dapat melakukan sesuatu yang mirip dengan Objek di JS, menggantikan Array untuk daftar, jika perlu.
Berikut kode Python yang saya gunakan untuk membuat dict pertama di atas:
sumber
Mungkin cara paling sederhana untuk mengubah data Anda menjadi hierarki adalah dengan memanfaatkan operator bersarang bawaan D3
d3.nest()
:Dengan mendaftarkan fungsi-fungsi utama via
nest.key()
Anda dapat dengan mudah menentukan struktur hierarki Anda. Sama seperti Gerardo yang dijabarkan dalam jawabannya, Anda dapat menggunakan.columns
properti yang terpapar pada array data setelah menguraikan CSV Anda untuk secara otomatis menghasilkan fungsi-fungsi utama ini. Seluruh kode bermuara pada baris berikut:Perhatikan, bagaimanapun, bahwa hierarki yang dihasilkan tidak persis menyerupai struktur yang diminta dalam pertanyaan Anda sebagai objek
{ key, values }
bukan{ name, children }
; Ngomong-ngomong, ini juga berlaku untuk jawaban Gerardo. Ini tidak sakit untuk kedua jawaban, karena hasilnya dapat diatasid3.hierarchy()
dengan menetapkan fungsi pengakses anak - anak :Demo berikut menyatukan semua bagian:
Tampilkan cuplikan kode
Anda mungkin juga ingin melihat kunci d3.nest () dan konversi nilai menjadi nama dan anak-anak jika Anda merasa perlu memiliki struktur yang diposting.
sumber
d3.nest
saat berlangsung: akan segera ditinggalkan.Tantangan yang menyenangkan. Coba kode javascript ini. Saya menggunakan set Lodash untuk kesederhanaan.
Ini menghasilkan hasil akhir (mirip) dengan apa yang Anda inginkan.
sumber
Bahkan, @Charles Merriam solusinya sangat elegan.
Jika Anda ingin membuat hasil yang sama dengan pertanyaan, maka cobalah sebagai berikut.
sumber