Python Pandas équivalent en JavaScript

91

Avec cet exemple CSV:

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

La méthode standard que j'utilise Pandas est la suivante:

  1. Analyser CSV

  2. Sélectionnez des colonnes dans un bloc de données ( col1et col3)

  3. Traiter la colonne (par exemple, calculer la moyenne des valeurs de col1et col3)

Existe-t-il une bibliothèque JavaScript qui fait cela comme Pandas?

Neversaint
la source
5
Faites-nous savoir avec quoi vous vous retrouvez. C'est une question importante pour beaucoup d'entre nous.
Ahmed Fasih

Réponses:

126

Toutes les réponses sont bonnes. En espérant que ma réponse est complète (c'est-à-dire essaie de lister toutes les options). J'espère revenir et réviser cette réponse avec tous les critères pour aider à faire un choix.

J'espère que tous ceux qui viennent ici connaissent d3. d3est un «couteau suisse» très utile pour gérer les données en Javascript, comme pandasc'est utile pour Python. Vous pouvez voir d3utilisé fréquemment comme pandas, même si ce d3n'est pas exactement un remplacement DataFrame / Pandas (c'est d3-à- dire n'a pas la même API; d3n'a pas Series/ DataFramequi se comporte comme dans pandas)

La réponse d'Ahmed explique comment d3 peut être utilisé pour obtenir certaines fonctionnalités de DataFrame, et certaines des bibliothèques ci-dessous ont été inspirées par des choses comme LearnJsData qui utilise d3et lodash.

En ce qui concerne les fonctionnalités axées sur DataFrame, j'ai été submergé par les bibliothèques JS qui aident. Voici une liste rapide de certaines des options que vous avez peut-être rencontrées. Je n'ai encore vérifié aucun d'entre eux en détail (la plupart ont été trouvés en combinaison avec la recherche Google + NPM).

Veillez à utiliser une variété avec laquelle vous pouvez travailler; certains sont Node.js aka Javascript côté serveur, certains sont compatibles avec le navigateur aka Javascript côté client. Certains sont dactylographiés.

  • pandas-js
    • D'après les réponses de STEEL et Feras
    • "pandas.js est une bibliothèque open source (expérimentale) imitant la bibliothèque pandas Python. Elle s'appuie sur Immutable.js comme équivalent logique NumPy. Les principaux objets de données de pandas.js sont, comme dans les pandas Python, la série et le DataFrame . "
  • dataframe-js
    • "DataFrame-js fournit une structure de données immuable pour javascript et datascience, le DataFrame, qui permet de travailler sur des lignes et des colonnes avec une API inspirée de la programmation SQL et fonctionnelle."
  • forge de données
  • jsdataframe
    • «Jsdataframe est une bibliothèque de gestion de données JavaScript inspirée de la fonctionnalité de trame de données dans R et Python Pandas.»
  • trame de données
    • "Explorer les données en les regroupant et en les réduisant."

Ensuite, après être arrivé à cette question, en vérifiant les autres réponses ici et en faisant plus de recherches, j'ai trouvé des options comme:

  • Apache Arrow dans JS
    • Merci à la suggestion de l'utilisateur Back2Basics:
    • "Apache Arrow est une spécification de disposition de mémoire en colonnes pour le codage de vecteurs et de conteneurs de type table de données plates et imbriquées. Apache Arrow est la norme émergente pour les grandes données en colonnes en mémoire (Spark, Pandas , Drill, Graphistry, ...)"
  • Observable
    • À première vue, cela semble être une JSalternative aux "notebooks" IPython / Jupyter
    • La page d'Observable promet: "Programmation réactive", une "Communauté", sur une "Plateforme Web"
    • Voir l'intro de 5 minutes ici
  • incliner (d'après la réponse de Rufus )
    • Je m'attendais à ce que l'accent soit mis sur l'API de DataFrame, que Pandas lui-même essaie de préserver de R documenter son remplacement / amélioration / correspondance à toutes les fonctions de R .
    • Au lieu de cela, je trouve que l'exemple d'inclinaison met l'accent sur la manière jQuery d'obtenir des données dans le DOMson (génial) Multiview (l'interface utilisateur), qui ne nécessite pas jQuery mais nécessite un navigateur! Plus d'exemples
    • ... ou un accent sur son architecture MVC-ish ; y compris des éléments back-end (par exemple, des connexions à la base de données)
    • Je suis probablement trop sévère; après tout, l'un des avantages des pandas est de savoir comment créer facilement des visualisations; hors de la boîte.
  • js-data
    • Vraiment plus d'un ORM ! La plupart de ses modules correspondent à des données de stockage de questions ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), le tri, le filtrage, etc.
    • Du côté positif fonctionne sur Node.js en première priorité; "Fonctionne dans Node.js et dans le navigateur."
  • miso (une autre suggestion de Rufus )
  • AlaSQL
    • "AlaSQL" est une base de données SQL open source pour Javascript avec un fort accent sur la vitesse de requête et la flexibilité des sources de données pour les données relationnelles et les données sans schéma. Il fonctionne dans votre navigateur, Node.js et Cordova. "
  • Quelques expériences de pensée:

J'espère que cet article pourra devenir un wiki communautaire et évaluer (c'est-à-dire comparer les différentes options ci-dessus) par rapport à différents critères tels que:

  • Critères de Panda dans sa comparaison R
    • Performance
    • Fonctionnalité / flexibilité
    • Facilité d'utilisation
  • Mes propres suggestions
    • Similitude avec les API Pandas / Dataframe
    • Frappe spécifiquement sur leurs principales caractéristiques
    • Accent sur la science des données> Accent sur l'interface utilisateur
    • Intégration démontrée en combinaison avec d'autres outils tels que Jupyter (blocs-notes interactifs), etc.

Certaines choses qu'une bibliothèque JS peut ne jamais faire (mais le pourrait-il?)

  • Utilisez un cadre sous-jacent qui est la meilleure bibliothèque de nombres / mathématiques Javascript de sa catégorie? (c'est-à-dire un équivalent d'un NumPy )
  • Utilisez toute optimisation / compilateur qui pourrait entraîner un code plus rapide (c'est-à-dire un équivalent de l'utilisation de Cython par Pandas )
  • Parrainé par tous les consortiums à saveur de science des données, ala Pandas et NumFocus
The Red Pea
la source
1
Merci pour ce merveilleux aperçu. Je connais à la fois l'utilisation des dataframes pandas et SQL. Quels sont les avantages (et les inconvénients) de l'utilisation de JS à l'aide de dataframes par rapport à une base de données SQL JS?
tardis
@molotow c'est une excellente question, mais je n'ai pas beaucoup d'expérience avec les bases de données JS SQL (bien qu'elles aient l'air cool). En général, je suppose que les approches de type trame de données prendraient en charge davantage de fonctions axées sur le «traitement des données» / «science des données», comme l'inférence de valeurs vides; faire des multiplications matricielles, etc. Alors qu'un SQL (JS) est plus axé sur les choses relationnelles: interrogation, tri, filtrage. Bien sûr, il y aura chevauchement; dataframe peut JOIN, trier et filtrer, tout comme SQL inclut des fonctions statistiques, etc. Quelqu'un d'autre a des idées?
The Red Pea
1
le fait qu'il y ait autant d'options est ennuyeux. Plutôt que la communauté se concentre sur une seule chose et la rendre bonne.
Claudiu Creanga
3
(L'auteur de Arrow JS ici) @ClaudiuCreanga Je comprends la frustration. Au départ, nous avons écrit ArrowJS pour tenter de combler le fossé entre les nœuds / navigateurs et les piles de Big Data plus traditionnelles, et nous avons investi le plus lourdement dans d'excellentes primitives IPC / streaming jusqu'à présent. Comme prochaines étapes, nous aimerions commencer à intégrer plus de bibliothèques JS (tensorflow, d3, etc.), et les PR sont toujours les bienvenus. Une approche alternative est des choses comme le projet Perspective de JPMC , qui utilise ArrowJS pour consommer et produire des tableaux Arrow.
ptaylor
1
existe-t-il une fonctionnalité pour la fusion de dataframe dans pandas équivalente en javascript?
Phani vikranth
9

J'ai travaillé sur une bibliothèque de data wrangling pour JavaScript appelée data-forge. Il est inspiré par LINQ et Pandas.

Il peut être installé comme ceci:

npm install --save data-forge

Votre exemple fonctionnerait comme ceci:

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

Si vos données étaient dans un fichier CSV, vous pouvez le charger comme ceci:

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

Vous pouvez utiliser la selectméthode pour transformer des lignes.

Vous pouvez extraire une colonne en utilisant, getSeriespuis utiliser la selectméthode pour transformer les valeurs de cette colonne.

Vous récupérez vos données de la trame de données comme ceci:

var data = dataFrame.toArray();

Pour faire la moyenne d'une colonne:

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

Vous pouvez faire beaucoup plus avec cela.

Vous pouvez trouver plus de documentation sur npm .

Ashley Davis
la source
7

Ceaveat Ce qui suit s'applique uniquement à d3 v3, et non à la dernière d4v4!

Je suis partisan de d3.js , et même s'il ne remplacera pas totalement les pandas, si vous passez du temps à apprendre son paradigme, il devrait être en mesure de prendre en charge toutes vos données à votre place. (Et si vous finissez par vouloir afficher les résultats dans le navigateur, c'est parfaitement adapté à cela.)

Exemple. Mon fichier CSV data.csv:

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

Dans le même répertoire, créez un index.htmlcontenant les éléments suivants:

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

et également un demo.jsfichier contenant les éléments suivants:

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

Dans le répertoire, exécutez python -m SimpleHTTPServer 8181et ouvrez http: // localhost: 8181 dans votre navigateur pour voir une liste simple des âges et de leur moyenne.

Cet exemple simple montre quelques fonctionnalités pertinentes de d3:

  • Excellent support pour l'ingestion de données en ligne ( CSV , TSV, JSON, etc.)
  • L'intelligence de la lutte contre les données intégrée
  • Manipulation DOM basée sur les données (peut-être la chose la plus difficile à comprendre): vos données sont transformées en éléments DOM.
Ahmed Fasih
la source
2
juste pour aider les futurs débutants - les instructions ci-dessus ne sont plus valables pour d3 v4. pense que l'étape de mappage est maintenant terminée dans le rappel de données, par exemple github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx
@swyx merci pour la tête haute, pouvez-vous corriger l'exemple et publier comme réponse?
Ahmed Fasih
@AhmedFasih Vous devriez corriger votre propre message pour le bénéfice de tous. De plus, swyx n'a pas assez de réputation pour éditer votre message.
Carles Alcolea
@CarlesAlcolea J'ai ajouté un gros avertissement en haut, désolé je n'ai pas le temps de me familiariser avec l'API actuelle pour le moment 😿
Ahmed Fasih
@AhmedFasih c'est mieux qu'avant :) Merci!
Carles Alcolea
5

Pandas.js est pour le moment une bibliothèque expérimentale, mais semble très prometteuse, elle utilise sous le capot immutable.js et la logique NumpPy, les séries d'objets de données et DataFrame sont là.

Feras
la source
3
Il semble que la bibliothèque n'ait pas eu de validation depuis plus de deux ans et semble avoir de nombreux problèmes. Je ne dirais pas «très prometteur».
jarthur
4

Ci-dessous se trouve Python numpy et 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)

''

La même chose peut être obtenue en JavaScript * [ numjs fonctionne uniquement avec Node.js ] Mais D3.js a beaucoup d'options avancées de jeu de fichiers de données. Numjs et Pandas-js sont toujours en travaux.

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

*/

ACIER
la source
3

Je pense que ce qui se rapproche le plus, ce sont des bibliothèques comme:

Recline en particulier a un objet Dataset avec une structure quelque peu similaire aux trames de données Pandas. Il vous permet ensuite de connecter vos données avec des "Vues" telles qu'une grille de données, des graphiques, des cartes, etc. Les vues sont généralement des enveloppes minces autour des meilleures bibliothèques de visualisation existantes telles que D3, Flot, SlickGrid, etc.

Voici un exemple pour Recline:

// Charger des données
var dataset = recline.Model.Dataset ({
  records: [
    {valeur: 1, date: '2012-08-07'},
    {valeur: 5, b: '2013-09-07'}
  ]
  // Charger les données CSV à la place
  // (And Recline prend en charge de nombreux autres types de sources de données)
  // url: 'mon-fichier-csv-local.csv',
  // backend: 'csv'
});

// récupère un élément de votre HTML pour le spectateur
var $ el = $ ('# visualiseur de données');

var allInOneDataViewer = nouveau recline.View.MultiView ({
  modèle: jeu de données,
  el: $ el
});
// Votre nouvelle visionneuse de données sera en ligne!
Rufus Pollock
la source
3

@neversaint votre attente est terminée. dites bienvenue à Danfo.js, qui est des pandas comme la bibliothèque Javascript construite sur tensorflow.js et prend en charge les tenseurs prêts à l'emploi. Cela signifie que vous pouvez convertir la structure de données danfo en Tensors. Et vous pouvez effectuer le groupby, la fusion, la jonction, le traçage et d'autres traitements de données.

Vignesh Prajapati
la source
1

Il est assez facile d'analyser CSV en javascript car chaque ligne est déjà essentiellement un tableau javascript. Si vous chargez votre csv dans un tableau de chaînes (une par ligne), il est assez facile de charger un tableau de tableaux avec les valeurs:

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

Renvoie ensuite getData()un tableau multidimensionnel de valeurs par colonne.

J'ai démontré cela dans un jsFiddle pour vous.

Bien sûr, vous ne pouvez pas le faire aussi facilement si vous ne faites pas confiance à l'entrée - s'il peut y avoir un script dans vos données qu'eval pourrait récupérer, etc.

Steve K
la source
Je sais que vous avez mis un avertissement dans votre réponse, mais je ne saurais trop insister sur la gravité de cette méthode du point de vue de la sécurité.
xApple
Ce n'est mauvais du point de vue de la sécurité que s'il ne fait pas confiance à l'entrée. Si, par exemple, il réalise un projet scolaire dans lequel il connaît déjà ses fichiers d'entrée (parce que lui ou son enseignant les a fournis à l'avance dans un format spécifique), il s'agit d'une solution compacte, simple et lisible. Il n'a donné aucun contexte concernant la source de ses entrées, demandez simplement un moyen de lire le CSV pour un traitement facile.
Steve K
1

Voici une approche dynamique supposant un en-tête existant sur la ligne 1. Le csv est chargé avec 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);         

});

Ensuite, vous êtes en mesure d'accéder à chaque colonne de données similaire à un dataframe R, python ou Matlab avec df.column_header[row_number].

Manuel
la source