Python Pandas equivalente in JavaScript


96

Con questo esempio CSV:

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

Il metodo standard che uso Pandas è questo:

  1. Parse CSV

  2. Seleziona le colonne in un data frame ( col1e col3)

  3. Elabora la colonna (ad es. Media i valori di col1e col3)

Esiste una libreria JavaScript che lo fa come Pandas?


6
Facci sapere cosa ti succederà. Questa è una domanda importante per molti di noi.
Ahmed Fasih

Risposte:


133

Tutte le risposte sono buone. Spero che la mia risposta sia esauriente (cioè cerca di elencare tutte le opzioni). Spero di tornare e rivedere questa risposta con qualsiasi criterio per aiutare a fare una scelta.

Spero che chiunque venga qui abbia familiarità con d3. d3è molto utile "coltellino svizzero" per la gestione dei dati in Javascript, come pandasè utile per Python. Potresti vedere d3usato frequentemente come pandas, anche se nond3 è esattamente una sostituzione DataFrame / Pandas (cioè d3non ha la stessa API; d3non ha Series/ DataFrameche si comporta come in pandas)

La risposta di Ahmed spiega come d3 può essere utilizzato per ottenere alcune funzionalità DataFrame e alcune delle librerie seguenti sono state ispirate da cose come LearnJsData che usa d3e lodash.

Per quanto riguarda le funzionalità incentrate su DataFrame, sono stato sopraffatto dalle librerie JS che aiutano. Ecco un breve elenco di alcune delle opzioni che potresti aver incontrato. Non ho ancora controllato nessuno di loro in dettaglio (la maggior parte l'ho trovata in combinazione Google + ricerca NPM).

Fai attenzione a utilizzare una varietà con cui puoi lavorare; alcuni sono Node.js aka Javascript lato server, alcuni sono compatibili con browser aka Javascript lato client. Alcuni sono dattiloscritti.

  • pandas-js
    • Dalle risposte di STEEL e Feras
    • "pandas.js è una libreria open source (sperimentale) che imita la libreria panda di Python. Si basa su Immutable.js come equivalente logico di NumPy. I principali oggetti di dati in pandas.js sono, come in Python panda, la serie e il DataFrame . "
  • dataframe-js
    • "DataFrame-js fornisce una struttura dati immutabile per javascript e datascience, il DataFrame, che permette di lavorare su righe e colonne con un sql e un'API ispirata alla programmazione funzionale."
  • data-forge
  • jsdataframe
    • "Jsdataframe è una libreria JavaScript di data wrangling ispirata alla funzionalità dei data frame in R e Python Pandas."
  • dataframe
    • "esplorare i dati raggruppandoli e riducendoli".

Quindi, dopo essere arrivato a questa domanda, controllando altre risposte qui e facendo più ricerche, ho trovato opzioni come:

  • Apache Arrow in JS
    • Grazie al suggerimento dell'utente Back2Basics:
    • "Apache Arrow è una specifica di layout di memoria colonnare per la codifica di vettori e contenitori simili a tabelle di dati piatti e nidificati. Apache Arrow è lo standard emergente per dati colonnari in memoria di grandi dimensioni (Spark, Pandas , Drill, Graphistry, ...)"
  • Osservabile
    • A prima vista, sembra JSun'alternativa ai "notebook" IPython / Jupyter
    • La pagina di Observable promette: "Reactive programming", una "Community", su una "Web Platform"
    • Guarda l'introduzione di 5 minuti qui
  • reclinare (dalla risposta di Rufus )
    • Mi aspettavo un'enfasi sull'API di DataFrame, che Pandas stessa cerca di fare preservare da R documentare la sua sostituzione / miglioramento / corrispondenza ad ogni funzione R .
    • Invece trovo un'enfasi che sottolinea l'esempio di sdraiarsi il modo jQuery di ottenere dati nel DOMil suo (fantastico) Multiview (l'interfaccia utente), che non richiede jQuery ma richiede un browser! Altri esempi
    • ... o un'enfasi sulla sua architettura MVC-ish ; comprese le cose di back-end (cioè le connessioni al database)
    • Probabilmente sono troppo duro; dopo tutto, una delle cose belle dei panda è come possono creare facilmente visualizzazioni; fuori dalla scatola.
  • js-data
    • Davvero più di un ORM ! La maggior parte dei suoi moduli corrispondono a differenti dati di stoccaggio domande ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), ordinamento, filtro, ecc
    • Il lato positivo funziona su Node.js come priorità assoluta; "Funziona in Node.js e nel browser."
  • miso (un altro suggerimento di Rufus )
  • AlaSQL
    • "AlaSQL" è un database SQL open source per Javascript con una forte attenzione alla velocità delle query e alla flessibilità dell'origine dati sia per i dati relazionali che per i dati senza schema. Funziona nel tuo browser, Node.js e Cordova. "
  • Alcuni esperimenti mentali:

Spero che questo post possa diventare un wiki della comunità e valutare (ovvero confrontare le diverse opzioni sopra) rispetto a criteri diversi come:

  • I criteri di Panda nel suo confronto R.
    • Prestazione
    • Funzionalità / flessibilità
    • Facile da usare
  • I miei suggerimenti
    • Somiglianza con le API di Pandas / Dataframe
    • In particolare colpisce le loro caratteristiche principali
    • Enfasi sulla scienza dei dati> Enfasi sull'interfaccia utente
    • Integrazione dimostrata in combinazione con altri strumenti come Jupyter (taccuini interattivi), ecc

Alcune cose che una libreria JS potrebbe non fare mai (ma potrebbe?)


1
Grazie per questa meravigliosa panoramica. Conosco sia l'uso di dataframe panda che SQL. Quali sono i vantaggi (e gli svantaggi) dell'utilizzo di JS utilizzando dataframe rispetto a un database JS SQL?
tardis

@molotow questa è un'ottima domanda, ma non ho molta esperienza con i database JS SQL (anche se sembrano interessanti). In generale, immagino che gli approcci di tipo dataframe supporterebbero più funzioni focalizzate "data wrangling" / "data science", come inferire valori vuoti; fare la moltiplicazione di matrici, ecc. Mentre un (JS) SQL è più focalizzato su cose relazionali: query, ordinamento, filtraggio. Ovviamente ci saranno sovrapposizioni; dataframe può JOIN, ordinare e filtrare, proprio come SQL include alcune funzioni statistiche e così via. Qualcun altro ha idee?
The Red Pea

1
il fatto che ci siano così tante opzioni è fastidioso. Piuttosto, fai in modo che la comunità si concentri su una sola cosa e rendila buona.
Claudiu Creanga

3
(L'autore di Arrow JS qui) @ClaudiuCreanga Capisco la frustrazione. Inizialmente abbiamo scritto ArrowJS nel tentativo di colmare il divario tra nodi / browser e stack di big data più tradizionali, e finora abbiamo investito molto in eccellenti primitive IPC / streaming. Come passaggi successivi, ci piacerebbe iniziare l'integrazione con più librerie JS (tensorflow, d3, ecc.) E i PR sono sempre i benvenuti. Un approccio alternativo è cose come il progetto Perspective di JPMC , che utilizza ArrowJS per consumare e produrre tabelle Arrow.
ptaylor

1
esiste una funzionalità per l'unione dei dataframe in panda equivalente a javascript?
Phani vikranth

9

Ho lavorato a una libreria di data wrangling per JavaScript chiamata data-forge. È ispirato a LINQ e Pandas.

Può essere installato in questo modo:

npm install --save data-forge

Il tuo esempio funzionerebbe in questo modo:

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" ])
        ;

Se i tuoi dati erano in un file CSV, potresti caricarlo in questo modo:

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

Puoi usare il selectmetodo per trasformare le righe.

È possibile estrarre una colonna utilizzando getSeriesquindi utilizzare il selectmetodo per trasformare i valori in quella colonna.

Ottieni i tuoi dati fuori dal data-frame in questo modo:

var data = dataFrame.toArray();

Per calcolare la media di una colonna:

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

C'è molto di più che puoi fare con questo.

È possibile trovare altra documentazione su npm .


8

Ceaveat Quanto segue è applicabile solo a d3 v3 e non all'ultimo d4v4!

Sono parziale a d3.js e, sebbene non sia un sostituto totale di Panda, se passi un po 'di tempo ad apprendere il suo paradigma, dovrebbe essere in grado di prendersi cura di tutti i tuoi dati discutendo per te. (E se finisci per voler visualizzare i risultati nel browser, è l'ideale per questo.)

Esempio. Il mio file CSV data.csv:

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

Nella stessa directory, crea un file index.htmlcontenente quanto segue:

<!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>

e anche un demo.jsfile contenente quanto segue:

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);
       });

Nella directory, esegui python -m SimpleHTTPServer 8181e apri http: // localhost: 8181 nel tuo browser per vedere un semplice elenco delle età e della loro media.

Questo semplice esempio mostra alcune caratteristiche rilevanti di d3:

  • Eccellente supporto per l'inserimento di dati online ( CSV , TSV, JSON, ecc.)
  • Intelligenza di negoziazione dei dati integrata
  • Manipolazione DOM basata sui dati (forse la cosa più difficile da capire): i tuoi dati vengono trasformati in elementi DOM.

2
solo per aiutare i futuri neofiti - le istruzioni di cui sopra non sono più valide per d3 v4. penso che la fase di mappatura sia eseguita all'interno del callback dei dati ora, ad esempio github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx

@swyx, grazie per l'avviso, puoi correggere l'esempio e pubblicare come risposta?
Ahmed Fasih

@AhmedFasih Dovresti correggere il tuo messaggio a vantaggio di tutti. Inoltre, swyx non ha abbastanza reputazione per modificare il tuo post.
Carles Alcolea

@CarlesAlcolea Ho aggiunto un grande disclaimer in alto, mi dispiace non ho tempo di aggiornarmi sull'API corrente in questo momento 😿
Ahmed Fasih

@AhmedFasih beh, è ​​meglio di prima :) Grazie!
Carles Alcolea

5

Di seguito è riportato Python numpy e panda

`` `

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)

`` `

Lo stesso può essere ottenuto in JavaScript * [ numjs funziona solo con Node.js ] Ma D3.js ha opzioni di set di file di dati molto avanzate. Sia numjs che Pandas-js ancora in lavorazione ..

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

*/


5

Pandas.js al momento è una libreria sperimentale, ma sembra molto promettente che utilizza sotto il cofano immutable.js e la logica NumpPy, entrambe le serie di oggetti dati e DataFrame sono lì ..


3
Sembra che la biblioteca non abbia avuto un impegno da oltre due anni e sembra che abbia molti problemi. Non direi "molto promettente".
jarthur

4

@neversaint la tua attesa è finita. dì il benvenuto a Danfo.js che è una libreria panda come Javascript costruita su tensorflow.js e supporta i tensori fuori dagli schemi. Ciò significa che puoi convertire la struttura dei dati danfo in tensori. E puoi raggruppare, unire, unire, tracciare e altre elaborazioni di dati.


3

Penso che la cosa più vicina siano le biblioteche come:

Recline in particolare ha un oggetto Dataset con una struttura in qualche modo simile ai frame di dati Pandas. Ti consente quindi di connettere i tuoi dati con "viste" come una griglia di dati, grafici, mappe ecc. Le viste sono generalmente sottili involucri attorno alle migliori librerie di visualizzazione esistenti come D3, Flot, SlickGrid ecc.

Ecco un esempio per Recline:

// Carica alcuni dati
var dataset = recline.Model.Dataset ({
  record: [
    {value: 1, date: "2012-08-07"},
    {value: 5, b: '2013-09-07'}
  ]
  // Carica invece i dati CSV
  // (And Recline ha il supporto per molti altri tipi di origini dati)
  // url: "my-local-csv-file.csv",
  // backend: "csv"
});

// ottieni un elemento dal tuo HTML per il visualizzatore
var $ el = $ ('# visualizzatore di dati');

var allInOneDataViewer = new recline.View.MultiView ({
  modello: set di dati,
  el: $ el
});
// Il tuo nuovo visualizzatore dati sarà attivo!

1

È abbastanza facile analizzare CSV in javascript perché ogni riga è già essenzialmente un array javascript. Se carichi il tuo csv in un array di stringhe (uno per riga) è abbastanza facile caricare un array di array con i valori:

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);
};

Quindi getData()restituisce una matrice multidimensionale di valori per colonna.

L'ho dimostrato in un jsFiddle per te.

Ovviamente, non puoi farlo abbastanza facilmente se non ti fidi dell'input - se nei tuoi dati potrebbe esserci uno script che eval potrebbe raccogliere, ecc.


So che hai messo un avvertimento nella tua risposta, ma non posso davvero sottolineare abbastanza quanto sia dannoso questo metodo dal punto di vista della sicurezza.
xApple

È solo un male dal punto di vista della sicurezza se non si fida dell'input. Se, ad esempio, sta facendo un progetto scolastico in cui conosce già i suoi file di input (perché lui o il suo insegnante li ha forniti in anticipo in un formato specifico), questa è una soluzione compatta, facile e leggibile. Non ha fornito alcun contesto riguardo alla fonte dei suoi input, ha solo chiesto un modo per leggere il CSV per una facile elaborazione.
Steve K

1

Ecco un approccio dinamico che presuppone un'intestazione esistente sulla riga 1. Il csv viene caricato con 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);         

});

Quindi puoi accedere a ciascuna colonna di dati simile a un dataframe R, Python o Matlab con df.column_header[row_number].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.