Odpowiednik Python Pandas w JavaScript

90

W tym przykładzie CSV:

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

Standardowa metoda, której używam Pandas, to:

  1. Przeanalizuj plik CSV

  2. Wybierz kolumny do ramki danych ( col1i col3)

  3. Przetwórz kolumnę (np. Uśrednij wartości col1i col3)

Czy istnieje biblioteka JavaScript, która lubi Pandy?

neversaint
źródło
5
Daj nam znać, z czym skończysz. Dla wielu z nas to ważne pytanie.
Ahmed Fasih

Odpowiedzi:

125

Wszystkie odpowiedzi są dobre. Mam nadzieję, że moja odpowiedź jest wyczerpująca (tj. Próbuje wymienić wszystkie opcje). Mam nadzieję, że wrócę i zrewiduję tę odpowiedź, uwzględniając wszelkie kryteria, które pomogą dokonać wyboru.

Mam nadzieję, że każdy, kto tu przyjeżdża, jest zaznajomiony d3. d3jest bardzo przydatny „szwajcarski scyzoryk” do obsługi danych w Javascript, podobnie jak pandasjest pomocny w Pythonie. Możesz zobaczyć , że jest d3używany często pandas, nawet jeśli nied3 jest dokładnie zamiennikiem DataFrame / Pandas (tj. d3Nie ma tego samego interfejsu API; d3nie maSeries / DataFramektóre zachowują się jak w pandas)

Odpowiedź Ahmeda wyjaśnia, w jaki sposób można użyć d3 do osiągnięcia niektórych funkcji DataFrame, a niektóre z poniższych bibliotek zostały zainspirowane takimi rzeczami, jak LearnJsData, które używają d3i lodash.

Jeśli chodzi o funkcje skoncentrowane na DataFrame, byłem przytłoczony bibliotekami JS, które pomagają. Oto krótka lista niektórych opcji, które mogłeś napotkać. Nie sprawdziłem jeszcze żadnego z nich szczegółowo (większość znalazłem w połączeniu wyszukiwania Google + NPM).

Uważaj, jeśli używasz różnych odmian, z którymi możesz pracować; niektóre to Node.js, czyli JavaScript po stronie serwera, inne są zgodne z przeglądarkami, czyli JavaScript po stronie klienta. Niektóre są maszynopisowe.

  • pandas-js
    • Od Steel and Feras 'odpowiedziach
    • „pandas.js to otwarta (eksperymentalna) biblioteka naśladująca bibliotekę Python pandas. Opiera się na Immutable.js jako logicznym odpowiedniku NumPy. Główne obiekty danych w pandas.js to, podobnie jak w pandach Pythona, Series i DataFrame ”.
  • dataframe-js
    • „DataFrame-js zapewnia niezmienną strukturę danych dla javascript i datascience, DataFrame, która umożliwia pracę z wierszami i kolumnami za pomocą interfejsu SQL i API inspirowanego programowaniem funkcjonalnym”
  • data-forge
    • Widziany w odpowiedzi Ashley Davis
    • „Zestaw narzędzi do transformacji i analizy danych JavaScript zainspirowany Pandas i LINQ”.
    • Zauważ, że stare repozytorium JS Data-forge nie jest już obsługiwane; teraz nowe repozytorium używa Typescript
  • jsdataframe
    • „Jsdataframe to biblioteka JavaScript do wymiany danych inspirowana funkcjami ramek danych w R i Python Pandas”.
  • ramka danych
    • „Eksploruj dane poprzez grupowanie i redukowanie”.

Następnie po przejściu do tego pytania, sprawdzeniu innych odpowiedzi tutaj i przeprowadzeniu dalszych poszukiwań, znalazłem opcje takie jak:

  • Apache Arrow w JS
    • Dzięki sugestii użytkownika Back2Basics:
    • „Apache Arrow to kolumna specyfikacja układu pamięci do kodowania wektorów i tabelarycznych kontenerów płaskich i zagnieżdżonych danych. Apache Arrow to wyłaniający się standard dla dużych kolumnowych danych w pamięci (Spark, Pandas , Drill, Graphistry, ...)”
  • Zauważalny
    • Na pierwszy rzut oka wydaje się być JSalternatywą dla „notebooków” IPython / Jupyter
    • Strona Observable obiecuje: „Programowanie reaktywne”, „Społeczność” na „Platformie internetowej”
    • Zobacz 5-minutowe wprowadzenie tutaj
  • leżeć (z odpowiedzi Rufusa )
    • Spodziewałem się położenia nacisku na API DataFrame, do którego próbuje się sama Pandas zachowaj od R. udokumentować swoje zapasowe / poprawę / korespondencję do każdej funkcji R .
    • Zamiast tego uważam, że przykład kładzie nacisk na recline sposób jQuery na pobieranie danych do DOMjego (niesamowity) Multiview (UI), który nie wymaga jQuery, ale wymaga przeglądarki! Więcej przykładów
    • ... lub nacisk na architekturę MVC ; w tym zaplecze (tj. połączenia z bazą danych)
    • Prawdopodobnie jestem zbyt surowy; w końcu jedną z fajnych rzeczy w pandach jest to, jak łatwo mogą tworzyć wizualizacje; po wyjęciu z pudełka.
  • js-data
    • Naprawdę bardziej ORM ! Większość z jego modułów odpowiadają różnym danych magazynowych pytań ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), sortowanie, filtrowanie, etc.
    • Po stronie plusów działa na Node.js jako priorytet; „Działa w Node.js i w przeglądarce”.
  • miso (kolejna sugestia Rufusa )
  • AlaSQL
    • „AlaSQL” to baza danych SQL typu open source dla języka JavaScript, która koncentruje się na szybkości zapytań i elastyczności źródła danych zarówno w przypadku danych relacyjnych, jak i danych bez schematów. Działa w Twojej przeglądarce, Node.js i Cordova ”.
  • Niektóre eksperymenty myślowe:

Mam nadzieję, że ten post stanie się wiki społeczności i oceni (tj. Porównaj różne opcje powyżej) pod kątem różnych kryteriów, takich jak:

  • Kryteria Pandy w porównaniu z R.
    • Występ
    • Funkcjonalność / elastyczność
    • Łatwość użycia
  • Moje własne sugestie
    • Podobieństwo do API Pandas / Dataframe
    • W szczególności uderza w ich główne cechy
    • Nacisk na naukę o danych> Nacisk na interfejs użytkownika
    • Demonstrowana integracja w połączeniu z innymi narzędziami, takimi jak Jupyter (interaktywne notebooki) itp

Niektórych rzeczy biblioteka JS może nigdy nie zrobić (ale czy mogłaby?)

Groszek czerwony
źródło
1
Dzięki za ten wspaniały przegląd. Znam zarówno użycie ramek danych pandy, jak i SQL. Jakie są zalety (i wady) używania JS przy użyciu ramek danych w porównaniu z bazą danych JS SQL?
tardis
@molotow to świetne pytanie, ale nie mam dużego doświadczenia z bazami danych JS SQL (choć wyglądają fajnie). Generalnie przypuszczam, że podejścia oparte na ramkach danych wspierałyby bardziej funkcje skoncentrowane na „poprawianiu danych” / „nauce o danych”, jak wnioskowanie o pustych wartościach; mnożenie macierzy itp. Podczas gdy (JS) SQL jest bardziej skoncentrowany na sprawach relacyjnych: zapytaniach, sortowaniu, filtrowaniu. Oczywiście będzie się pokrywać; dataframe może łączyć, sortować i filtrować, podobnie jak SQL zawiera pewne funkcje statystyczne itp. Czy ktoś jeszcze ma pomysły?
The Red Pea
1
fakt, że jest tak wiele opcji, jest denerwujący. Skoncentruj się raczej na jednej rzeczy i uczyń ją dobrą.
Claudiu Creanga
3
(Autor Arrow JS tutaj) @ClaudiuCreanga Rozumiem frustrację. Początkowo napisaliśmy ArrowJS, próbując zniwelować przepaść między węzłami / przeglądarkami a bardziej tradycyjnymi stosami dużych zbiorów danych i jak dotąd zainwestowaliśmy najwięcej w doskonałe prymitywy IPC / strumieniowania. W następnych krokach chcielibyśmy rozpocząć integrację z większą liczbą bibliotek JS (tensorflow, d3 itp.), A pliki PR są zawsze mile widziane. Alternatywnym podejściem są rzeczy takie jak projekt JPMC Perspective , który wykorzystuje ArrowJS do konsumowania i tworzenia tabel Arrow.
ptaylor
1
Czy istnieje funkcja scalania ramek danych w odpowiedniku pand w javascript?
Phani vikranth
9

Pracowałem nad biblioteką do edycji danych dla JavaScript o nazwie data-forge. Jest inspirowany LINQ i Pandas.

Można go zainstalować w następujący sposób:

npm install --save data-forge

Twój przykład działałby tak:

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

Jeśli twoje dane były w pliku CSV, możesz je załadować w ten sposób:

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

Możesz użyć tej selectmetody do przekształcenia wierszy.

Możesz wyodrębnić kolumnę za pomocą, getSeriesa następnie użyć selectmetody do przekształcenia wartości w tej kolumnie.

Otrzymujesz dane z powrotem z ramki danych w następujący sposób:

var data = dataFrame.toArray();

Aby uśrednić kolumnę:

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

Możesz z tym zrobić znacznie więcej.

Więcej dokumentacji na npm .

Ashley Davis
źródło
6

Ceaveat Poniższe informacje dotyczą tylko d3 v3, a nie najnowszego d4v4!

Jestem stronniczy w stosunku do d3.js i chociaż nie zastąpi on całkowicie Pandy, jeśli poświęcisz trochę czasu na naukę jego paradygmatu, powinien on być w stanie zająć się wszystkimi twoimi danymi. (A jeśli zechcesz wyświetlać wyniki w przeglądarce, idealnie się do tego nadaje).

Przykład. Mój plik CSV data.csv:

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

W tym samym katalogu utwórz plik index.htmlzawierający:

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

a także demo.jsplik zawierający:

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

W katalogu uruchom python -m SimpleHTTPServer 8181 i otwórz http: // localhost: 8181 w przeglądarce, aby zobaczyć prostą listę wieków i ich średnią.

Ten prosty przykład pokazuje kilka istotnych cech d3:

  • Doskonała obsługa przetwarzania danych online ( CSV , TSV, JSON itp.)
  • Pojawiły się sprytne sprytne dane
  • Manipulacja DOM oparta na danych (być może najtrudniejsza rzecz do ogarnięcia głowy): Twoje dane są przekształcane w elementy DOM.
Ahmed Fasih
źródło
2
tylko po to, aby pomóc przyszłym nowicjuszom - powyższe instrukcje nie są już ważne dla d3 v4. myślę, że etap mapowania odbywa się teraz w wywołaniu zwrotnym danych, np. github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx
@swyx dzięki za ostrzeżenie, czy możesz poprawić przykład i opublikować jako odpowiedź?
Ahmed Fasih
@AhmedFasih Dla dobra wszystkich powinieneś poprawić swój post. Ponadto swyx nie ma wystarczającej reputacji, aby edytować Twój post.
Carles Alcolea
@CarlesAlcolea Na górze dodałem duże zastrzeżenie, przepraszam, że nie mam teraz czasu, aby przyspieszyć działanie obecnego API 😿
Ahmed Fasih
@AhmedFasih cóż, to lepiej niż wcześniej :) Dzięki!
Carles Alcolea,
5

Obecnie Pandas.js jest biblioteką eksperymentalną, ale wydaje się bardzo obiecująca, że ​​wykorzystuje logikę immutable.js i NumpPy, zarówno serie obiektów danych, jak i DataFrame.

Feras
źródło
3
Wygląda na to, że biblioteka nie miała zobowiązania od ponad dwóch lat i wydaje się, że ma wiele problemów. Nie powiedziałbym „bardzo obiecujące”.
jarthur
4

Poniżej znajduje się Python numpy i pandy

`` ''

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)

`` ''

To samo można osiągnąć w JavaScript * [ numjs działa tylko z Node.js ] Ale D3.js ma znacznie zaawansowane opcje zestawu plików danych. Zarówno numjs, jak i Pandas-js nadal działają.

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

*/

STAL
źródło
3

Myślę, że najbliższe są biblioteki takie jak:

W szczególności Recline ma obiekt Dataset o strukturze nieco podobnej do ramek danych Pandas. Następnie umożliwia połączenie danych z „widokami”, takimi jak siatka danych, wykresy, mapy itp. Widoki są zwykle cienkimi opakowaniami wokół istniejących najlepszych bibliotek wizualizacji, takich jak D3, Flot, SlickGrid itp.

Oto przykład dla Recline:

// Załaduj trochę danych
var dataset = recline.Model.Dataset ({
  rekordy: [
    {value: 1, date: '2012-08-07'},
    {wartość: 5, b: „2013-09-07”}
  ]
  // Zamiast tego załaduj dane CSV
  // (A Recline obsługuje wiele innych typów źródeł danych)
  // url: 'my-local-csv-file.csv',
  // backend: „csv”
});

// pobierz element ze swojego kodu HTML dla przeglądarki
var $ el = $ ('# przeglądarka danych');

var allInOneDataViewer = new recline.View.MultiView ({
  model: zbiór danych,
  el: $ el
});
// Twoja nowa przeglądarka danych będzie dostępna!
Rufus Pollock
źródło
3

@neversaint Twoje oczekiwanie się skończyło. witamy w Danfo.js, który jest pandą, taką jak biblioteka Javascript zbudowana na tensorflow.js i obsługuje tensory po wyjęciu z pudełka. Oznacza to, że możesz przekonwertować strukturę danych danfo na tensory. Możesz też grupować, scalać, łączyć, kreślić i przetwarzać inne dane.

Vignesh Prajapati
źródło
1

Bardzo łatwo jest przeanalizować CSV w javascript, ponieważ każda linia jest już zasadniczo tablicą javascript. Jeśli załadujesz swój plik csv do tablicy ciągów (po jednym w wierszu), całkiem łatwo jest załadować tablicę tablic z wartościami:

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

Następnie getData()zwraca wielowymiarową tablicę wartości według kolumn.

Pokazałem to dla ciebie w jsFiddle .

Oczywiście nie możesz tego zrobić tak łatwo, jeśli nie ufasz danym wejściowym - jeśli w twoich danych może znajdować się skrypt, który eval mógłby odebrać itp.

Steve K.
źródło
Wiem, że umieściłeś ostrzeżenie w swojej odpowiedzi, ale naprawdę nie mogę wystarczająco podkreślić, jak zła jest ta metoda z punktu widzenia bezpieczeństwa.
xApple
Z punktu widzenia bezpieczeństwa jest to tylko złe, jeśli nie ufa danym wejściowym. Jeśli np. Realizuje projekt szkolny, w którym zna już swoje pliki wejściowe (ponieważ on lub jego nauczyciel dostarczył je wcześniej w określonym formacie), jest to kompaktowe, łatwe i czytelne rozwiązanie. Nie podał żadnego kontekstu dotyczącego źródła swoich danych wejściowych, po prostu poprosił o sposób odczytania pliku CSV w celu łatwego przetwarzania.
Steve K
1

Oto dynamiczne podejście zakładające istnienie nagłówka w linii 1. Plik csv jest ładowany 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);         

});

Następnie możesz uzyskać dostęp do każdej kolumny danych, podobnie jak w ramce danych R, Python lub Matlab df.column_header[row_number].

Manuel
źródło