Setara dengan Python Pandas dalam JavaScript

91

Dengan contoh CSV ini:

   Source,col1,col2,col3
   foo,1,2,3
   bar,3,4,5

Metode standar yang saya gunakan Pandas adalah ini:

  1. Parse CSV

  2. Pilih kolom ke dalam bingkai data ( col1dan col3)

  3. Proses kolom (misalnya rata-rata nilai col1dan col3)

Apakah ada pustaka JavaScript yang seperti Pandas?

neversaint
sumber
5
Beri tahu kami apa yang akan Anda lakukan. Ini adalah pertanyaan penting bagi banyak dari kita.
Ahmed Fasih

Jawaban:

126

Semua jawaban bagus. Berharap jawaban saya lengkap (yaitu mencoba mendaftar semua opsi). Saya berharap untuk kembali dan merevisi jawaban ini dengan kriteria apa pun untuk membantu membuat pilihan.

Saya harap siapa pun yang datang ke sini mengenalnya d3. d3sangat berguna "swiss army knife" untuk menangani data dalam Javascript, seperti pandasberguna untuk Python. Anda mungkin lihat d3sering digunakan seperti pandas, bahkan jika d3ini tidak tepat pengganti DataFrame / Panda (yaitu d3tidak memiliki API yang sama; d3tidak memiliki Series/ DataFrameyang berperilaku seperti di pandas)

Jawaban Ahmed menjelaskan bagaimana d3 dapat digunakan untuk mencapai beberapa fungsionalitas DataFrame, dan beberapa pustaka di bawah ini terinspirasi oleh hal-hal seperti LearnJsData yang menggunakan d3dan lodash.

Sedangkan untuk fitur yang berfokus pada DataFrame, saya kewalahan dengan pustaka JS yang membantu. Berikut daftar singkat dari beberapa opsi yang mungkin Anda temui. Saya belum memeriksanya secara detail (Kebanyakan saya temukan dalam kombinasi pencarian Google + NPM).

Hati-hati Anda menggunakan varietas yang bisa Anda gunakan; beberapa adalah Node.js alias Javascript sisi server, beberapa kompatibel dengan browser alias Javascript sisi klien. Beberapa adalah Ketikan.

  • pandas-js
    • Dari jawaban STEEL dan Feras
    • "pandas.js adalah pustaka open source (eksperimental) yang meniru pustaka pandas Python. Ini bergantung pada Immutable.js sebagai padanan logika NumPy. Objek data utama di pandas.js adalah, seperti di pandas Python, Seri dan DataFrame . "
  • dataframe-js
    • "DataFrame-js menyediakan struktur data yang tidak dapat diubah untuk javascript dan ilmu data, DataFrame, yang memungkinkan untuk bekerja pada baris dan kolom dengan sql dan api yang terinspirasi dari pemrograman fungsional."
  • data-forge
    • Terlihat dalam jawaban Ashley Davis
    • "Transformasi data JavaScript dan toolkit analisis yang terinspirasi oleh Pandas dan LINQ."
    • Perhatikan bahwa repositori JS data-forge lama tidak lagi dipertahankan; sekarang repositori baru menggunakan Typecript
  • jsdataframe
    • "Jsdataframe adalah pustaka pertengkaran data JavaScript yang terinspirasi oleh fungsionalitas bingkai data di R dan Python Pandas."
  • dataframe
    • "jelajahi data dengan mengelompokkan dan mengurangi".

Kemudian setelah datang ke pertanyaan ini, memeriksa jawaban lain di sini dan melakukan lebih banyak pencarian, saya menemukan opsi seperti:

  • Apache Arrow di JS
    • Terima kasih untuk saran Back2Basics pengguna:
    • "Apache Arrow adalah spesifikasi tata letak memori berbentuk kolom untuk penyandian vektor dan penampung seperti tabel dari data datar dan bersarang. Apache Arrow adalah standar yang muncul untuk data kolom dalam memori yang besar (Spark, Pandas , Drill, Graphistry, ...)"
  • Tampak
    • Sekilas, sepertinya JSalternatif dari "notebook" IPython / Jupyter
    • Halaman Observable menjanjikan: "Pemrograman reaktif", "Komunitas", di "Platform Web"
    • Lihat intro 5 menit di sini
  • berbaring (dari jawaban Rufus )
    • Saya mengharapkan penekanan pada API DataFrame, yang coba dilakukan Pandas sendiri melestarikan dari R mendokumentasikan penggantinya / perbaikan / korespondensi untuk setiap fungsi R .
    • Sebaliknya saya menemukan penekanan contoh berbaring itu cara jQuery memasukkan data ke DOMMultiview-nya (mengagumkan) (UI), yang tidak memerlukan jQuery tetapi membutuhkan browser! Lebih banyak contoh
    • ... atau penekanan pada arsitektur MVC-ish ; termasuk hal-hal back-end (yaitu koneksi database)
    • Saya mungkin terlalu kasar; lagipula, salah satu hal yang menyenangkan tentang panda adalah bagaimana ia dapat membuat visualisasi dengan mudah; keluar dari kotak.
  • js-data
    • Benar-benar lebih dari ORM ! Sebagian besar modul-modulnya sesuai dengan data yang berbeda penyimpanan pertanyaan ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), pemilahan, penyaringan, dll
    • Sisi positifnya bekerja pada Node.js sebagai prioritas pertama; "Bekerja di Node.js dan di Browser."
  • miso (saran lain dari Rufus )
  • AlaSQL
    • "AlaSQL" adalah database SQL open source untuk Javascript dengan fokus yang kuat pada kecepatan kueri dan fleksibilitas sumber data untuk data relasional dan data tanpa skema. Ini berfungsi di browser Anda, Node.js, dan Cordova. "
  • Beberapa eksperimen pikiran:

Saya berharap posting ini dapat menjadi wiki komunitas, dan mengevaluasi (yaitu membandingkan berbagai opsi di atas) terhadap berbagai kriteria seperti:

  • Kriteria Panda dalam perbandingan R.
    • Performa
    • Fungsionalitas / fleksibilitas
    • Kemudahan penggunaan
  • Saran saya sendiri
    • Kemiripan dengan Pandas / Dataframe API
    • Secara khusus mengenai fitur utama mereka
    • Penekanan ilmu data> Penekanan UI
    • Integrasi yang ditunjukkan dalam kombinasi dengan alat lain seperti Jupyter (notebook interaktif), dll

Beberapa hal yang mungkin tidak pernah dilakukan pustaka JS (tapi bisakah?)

The Red Pea
sumber
1
Terima kasih untuk ikhtisar yang luar biasa ini. Saya tahu penggunaan pandas dataframes dan SQL. Apa keuntungan (dan kerugian) menggunakan JS menggunakan dataframe versus database JS SQL?
tardis
@molotow ini adalah pertanyaan yang bagus, tapi saya tidak punya banyak pengalaman dengan database JS SQL (meskipun mereka terlihat keren). Secara umum saya akan menebak bahwa pendekatan tipe dataframe akan mendukung lebih banyak fungsi terfokus "data wrangling" / "data-science", seperti menyimpulkan nilai-nilai kosong; melakukan perkalian matriks, dll. Sedangkan (JS) SQL lebih fokus pada hal-hal relasional: query, sortir, filtering. Tentu akan ada tumpang tindih; dataframe dapat BERGABUNG, mengurutkan, dan memfilter, seperti SQL menyertakan beberapa fungsi statistik dan lain-lain. Ada yang punya ide?
Kacang Merah
1
fakta bahwa ada begitu banyak pilihan yang mengganggu. Lebih baik komunitas memusatkan perhatian pada satu hal saja dan menjadikannya baik.
Claudiu Creanga
3
(Panah JS penulis di sini) @ClaudiuCreanga Saya mengerti frustrasi. Awalnya kami menulis ArrowJS dalam upaya menjembatani kesenjangan antara node / browser dan tumpukan data besar yang lebih tradisional, dan kami telah berinvestasi paling banyak dalam IPC / streaming primitif yang sangat baik sejauh ini. Sebagai langkah selanjutnya, kami ingin mulai berintegrasi dengan lebih banyak JS libs (tensorflow, d3, dll.), Dan PR selalu diterima. Pendekatan alternatif adalah hal-hal seperti proyek Perspektif JPMC , yang menggunakan ArrowJS untuk mengkonsumsi dan menghasilkan tabel Arrow.
ptaylor
1
apakah ada fungsi untuk penggabungan dataframe dalam pandas yang setara di javascript?
Phani vikranth
9

Saya telah mengerjakan pustaka pertengkaran data untuk JavaScript yang disebut data-forge. Ini terinspirasi oleh LINQ dan Pandas.

Itu dapat diinstal seperti ini:

npm install --save data-forge

Contoh Anda akan bekerja seperti ini:

var csvData = "Source,col1,col2,col3\n" +
    "foo,1,2,3\n" +
    "bar,3,4,5\n";

var dataForge = require('data-forge');
var dataFrame = 
    dataForge.fromCSV(csvData)
        .parseInts([ "col1", "col2", "col3" ])
        ;

Jika data Anda berada dalam file CSV, Anda dapat memuatnya seperti ini:

var dataFrame = dataForge.readFileSync(fileName)
    .parseCSV()
    .parseInts([ "col1", "col2", "col3" ])
    ;

Anda dapat menggunakan selectmetode ini untuk mengubah baris.

Anda dapat mengekstrak kolom menggunakan getSerieslalu menggunakan selectmetode untuk mengubah nilai di kolom itu.

Anda mendapatkan data Anda kembali dari bingkai data seperti ini:

var data = dataFrame.toArray();

Untuk rata-rata kolom:

 var avg = dataFrame.getSeries("col1").average();

Masih banyak lagi yang dapat Anda lakukan dengan ini.

Anda dapat menemukan lebih banyak dokumentasi di npm .

Ashley Davis
sumber
7

Ceaveat Berikut ini hanya berlaku untuk d3 v3, dan bukan d4v4 terbaru!

Saya lebih memilih d3.js , dan meskipun ini tidak akan menjadi pengganti total untuk Pandas, jika Anda meluangkan waktu mempelajari paradigmanya, ia harus dapat menangani semua data Anda yang bertengkar untuk Anda. (Dan jika Anda akhirnya ingin menampilkan hasil di browser, itu idealnya cocok untuk itu.)

Contoh. File CSV saya data.csv:

name,age,color
Mickey,65,black
Donald,58,white
Pluto,64,orange

Di direktori yang sama, buat yang index.htmlberisi berikut ini:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>My D3 demo</title>

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  </head>
  <body>

      <script charset="utf-8" src="demo.js"></script>
  </body>
</html>

dan juga demo.jsfile yang berisi berikut ini:

d3.csv('/data.csv',

       // How to format each row. Since the CSV file has a header, `row` will be
       // an object with keys derived from the header.
       function(row) {
         return {name : row.name, age : +row.age, color : row.color};
       },

       // Callback to run once all data's loaded and ready.
       function(data) {
         // Log the data to the JavaScript console
         console.log(data);

         // Compute some interesting results
         var averageAge = data.reduce(function(prev, curr) {
           return prev + curr.age;
         }, 0) / data.length;

         // Also, display it
         var ulSelection = d3.select('body').append('ul');
         var valuesSelection =
             ulSelection.selectAll('li').data(data).enter().append('li').text(
                 function(d) { return d.age; });
         var totalSelection =
             ulSelection.append('li').text('Average: ' + averageAge);
       });

Di direktori, jalankan python -m SimpleHTTPServer 8181, dan buka http: // localhost: 8181 di browser Anda untuk melihat daftar sederhana usia dan rata-ratanya.

Contoh sederhana ini menunjukkan beberapa fitur d3 yang relevan:

  • Dukungan yang sangat baik untuk menyerap data online ( CSV , TSV, JSON, dll.)
  • Kecerdasan perebutan data muncul
  • Manipulasi DOM berdasarkan data (mungkin hal tersulit untuk dipahami): data Anda diubah menjadi elemen DOM.
Ahmed Fasih
sumber
2
hanya untuk membantu pemula di masa mendatang - petunjuk di atas tidak lagi berlaku untuk d3 v4. berpikir bahwa tahap pemetaan sudah dilakukan dalam panggilan balik data sekarang misalnya github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx
@swyx terima kasih atas perhatiannya, dapatkah Anda memperbaiki contoh dan memposting sebagai jawaban?
Ahmed Fasih
@AhmedFasih Anda harus mengoreksi postingan Anda sendiri untuk kepentingan semua orang. Selain itu, swyx tidak memiliki reputasi yang cukup untuk mengedit postingan Anda.
Carles Alcolea
@CarlesAlcolea Saya menambahkan penafian besar di bagian atas, maaf saya tidak punya waktu untuk mengetahui API saat ini sekarang 😿
Ahmed Fasih
@AhmedFasih lebih baik dari sebelumnya :) Terima kasih!
Carles Alcolea
5

Pandas.js saat ini adalah pustaka eksperimental, tetapi tampaknya sangat menjanjikan karena menggunakan logika immutable.js dan NumpPy, baik seri objek data dan DataFrame ada di sana ..

Feras
sumber
3
Sepertinya perpustakaan tersebut tidak memiliki komitmen selama lebih dari dua tahun, dan tampaknya memiliki banyak masalah. Saya tidak akan mengatakan 'sangat menjanjikan'.
jarthur
4

Di bawah ini adalah Python numpy dan pandas

``

import numpy as np
import pandas as pd

data_frame = pd.DataFrame(np.random.randn(5, 4), ['A', 'B', 'C', 'D', 'E'], [1, 2, 3, 4])

data_frame[5] = np.random.randint(1, 50, 5)

print(data_frame.loc[['C', 'D'], [2, 3]])

# axis 1 = Y | 0 = X
data_frame.drop(5, axis=1, inplace=True)

print(data_frame)

``

Hal yang sama dapat dicapai di JavaScript * [ numjs hanya berfungsi dengan Node.js ] Tetapi D3.js memiliki banyak opsi kumpulan file Data lanjutan. Baik numjs dan Pandas-js masih dalam pengerjaan ..

import np from 'numjs';
import { DataFrame } from 'pandas-js';

const df = new DataFrame(np.random.randn(5, 4), ['A', 'B', 'C', 'D', 'E'], [1, 2, 3, 4])

// df
/*

          1         2         3         4
A  0.023126  1.078130 -0.521409 -1.480726
B  0.920194 -0.201019  0.028180  0.558041
C -0.650564 -0.505693 -0.533010  0.441858
D -0.973549  0.095626 -1.302843  1.109872
E -0.989123 -1.382969 -1.682573 -0.637132

*/

BAJA
sumber
3

Saya pikir yang paling dekat adalah perpustakaan seperti:

Recline khususnya memiliki objek Kumpulan Data dengan struktur yang agak mirip dengan bingkai data Pandas. Kemudian memungkinkan Anda untuk menghubungkan data Anda dengan "Tampilan" seperti kisi data, grafik, peta, dll. Tampilan biasanya berupa pembungkus tipis di sekitar perpustakaan visualisasi terbaik yang ada seperti D3, Flot, SlickGrid, dll.

Inilah contoh untuk Recline:

// Muat beberapa data
var dataset = recline.Model.Dataset ({
  catatan: [
    {nilai: 1, tanggal: '2012-08-07'},
    {nilai: 5, b: '2013-09-07'}
  ]
  // Muat data CSV sebagai gantinya
  // (Dan Recline memiliki dukungan untuk lebih banyak jenis sumber data)
  // url: 'my-local-csv-file.csv',
  // backend: 'csv'
});

// dapatkan elemen dari HTML Anda untuk pemirsa
var $ el = $ ('# data-viewer');

var allInOneDataViewer = recline.View.MultiView baru ({
  model: dataset,
  el: $ el
});
// Penampil Data baru Anda akan ditayangkan!
Rufus Pollock
sumber
3

@neversaint, penantian Anda telah berakhir. ucapkan selamat datang di Danfo.js yang merupakan pustaka seperti pandas Javascript yang dibangun di atas tensorflow.js dan mendukung tensor di luar kotak. Ini berarti Anda dapat mengubah struktur data danfo menjadi Tensor. Dan Anda dapat melakukan groupby, merging, join, plotting dan pengolahan data lainnya.

Vignesh Prajapati
sumber
1

Sangat mudah untuk mengurai CSV dalam javascript karena setiap baris pada dasarnya sudah merupakan larik javascript. Jika Anda memuat csv Anda ke dalam array string (satu per baris), cukup mudah untuk memuat array array dengan nilai:

var pivot = function(data){
    var result = [];
    for (var i = 0; i < data.length; i++){
        for (var j=0; j < data[i].length; j++){
            if (i === 0){
                result[j] = [];
            }
            result[j][i] = data[i][j];
        }
    }
    return result;
};

var getData = function() {
    var csvString = $(".myText").val();
    var csvLines = csvString.split(/\n?$/m);

    var dataTable = [];

    for (var i = 0; i < csvLines.length; i++){
        var values;
        eval("values = [" + csvLines[i] + "]");
        dataTable[i] = values;
    }

    return pivot(dataTable);
};

Kemudian getData()mengembalikan larik nilai multidimensi menurut kolom.

Saya telah mendemonstrasikan ini di jsFiddle untuk Anda.

Tentu saja, Anda tidak dapat melakukannya dengan mudah jika Anda tidak mempercayai input - jika mungkin ada skrip di data Anda yang mungkin diambil eval, dll.

Steve K
sumber
Saya tahu Anda memberi peringatan dalam jawaban Anda, tetapi saya benar-benar tidak bisa cukup menekankan betapa buruknya metode ini dari sudut pandang keamanan.
xApple
Ini hanya buruk dari sudut pandang keamanan jika dia tidak mempercayai masukannya. Jika, misalnya, dia sedang mengerjakan proyek sekolah di mana dia sudah mengetahui file inputnya (karena dia atau gurunya telah menyediakannya sebelumnya dalam format tertentu), ini adalah solusi yang ringkas, mudah, dan dapat dibaca. Ia tidak memberikan konteks apapun terkait sumber masukannya, hanya menanyakan cara membaca CSV agar mudah diproses.
Steve K
1

Berikut adalah pendekatan dinamis dengan asumsi tajuk yang ada di baris 1. Csv dimuat d3.js.

function csvToColumnArrays(csv) {

    var mainObj = {},
    header = Object.keys(csv[0]);

    for (var i = 0; i < header.length; i++) {

        mainObj[header[i]] = [];
    };

    csv.map(function(d) {

        for (key in mainObj) {
            mainObj[key].push(d[key])
        }

    });        

    return mainObj;

}


d3.csv(path, function(csv) {

    var df = csvToColumnArrays(csv);         

});

Kemudian Anda dapat mengakses setiap kolom data yang mirip dengan dataframe R, python atau Matlab df.column_header[row_number].

Manuel
sumber