Эквивалент Python Pandas в JavaScript


91

В этом примере CSV:

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

Стандартный метод, который я использую Pandas, таков:

  1. Разобрать CSV

  2. Выберите столбцы во фрейме данных ( col1и col3)

  3. Обработка столбца (например, среднее значение col1и col3)

Есть ли библиотека JavaScript, которая похожа на Pandas?


5
Сообщите нам, чем вы закончите. Это важный вопрос для многих из нас.
Ахмед Фасих

Ответы:


126

Все ответы хороши. Надеюсь, что мой ответ исчерпывающий (т.е. пытается перечислить все варианты). Я надеюсь вернуться и пересмотреть этот ответ с любыми критериями, которые помогут сделать выбор.

Я надеюсь, что все, кто сюда приезжает, знакомы с d3. d3очень полезный «швейцарский армейский нож» для обработки данных в Javascript, как pandasи в Python. Вы можете d3часто видеть, как используется pandas, даже если d3это не совсем замена DataFrame / Pandas (т.е. d3не имеет того же API; d3не имеет Series/ DataFrameкоторые ведут себя как в pandas)

Ответ Ахмеда объясняет, как d3 можно использовать для достижения некоторых функций DataFrame, а некоторые из приведенных ниже библиотек были вдохновлены такими вещами, как LearnJsData, которые используют d3и lodash.

Что касается функций, ориентированных на DataFrame, я был поражен библиотеками JS, которые помогают. Вот краткий список некоторых вариантов, с которыми вы могли столкнуться. Я еще не проверял ни одного из них подробно (большинство из них я нашел в сочетании поиска Google + NPM).

Будьте осторожны, вы используете разнообразие, с которым можете работать; некоторые из них являются Node.js или серверным Javascript, некоторые - совместимыми с браузером или клиентскими Javascript. Некоторые из них - машинописный текст.

  • pandas-js
    • Из ответов STEEL и Feras
    • "pandas.js - это (экспериментальная) библиотека с открытым исходным кодом, имитирующая библиотеку Python pandas. Она полагается на Immutable.js в качестве логического эквивалента NumPy. Основными объектами данных в pandas.js являются, как и в Python pandas, Series и DataFrame . "
  • dataframe-js
    • «DataFrame-js предоставляет неизменяемую структуру данных для javascript и науки о данных, DataFrame, который позволяет работать со строками и столбцами с помощью sql и API, вдохновленного функциональным программированием».
  • кузница данных
    • Видно в ответе Эшли Дэвис
    • «Набор инструментов для преобразования и анализа данных JavaScript, вдохновленный Pandas и LINQ».
    • Обратите внимание, что старый репозиторий data-forge JS больше не поддерживается; теперь новый репозиторий использует Typescript
  • jsdataframe
    • «Jsdataframe - это библиотека обработки данных JavaScript, вдохновленная функциональностью фреймов данных в R и Python Pandas».
  • фрейм данных
    • «исследовать данные путем группировки и сокращения».

Затем, подойдя к этому вопросу, проверив здесь другие ответы и продолжив поиск, я нашел такие варианты, как:

  • Apache Arrow в JS
    • Благодаря предложению пользователя Back2Basics:
    • «Apache Arrow - это спецификация столбчатой ​​структуры памяти для кодирования векторов и табличных контейнеров плоских и вложенных данных. Apache Arrow - это развивающийся стандарт для больших столбчатых данных в памяти (Spark, Pandas , Drill, Graphistry, ...)»
  • Наблюдаемый
    • На первый взгляд кажется JSальтернативой «записным книжкам » IPython / Jupyter.
    • Страница Observable обещает: «Реактивное программирование», «Сообщество» на «Веб-платформе»
    • Смотрите 5-минутное вступление здесь
  • откидываться (из ответа Руфуса )
    • Я ожидал, что упор будет сделан на API DataFrame, который пытается сделать сама Pandas. сохранить из R документировать его замену / улучшения / соответствие каждой функции R .
    • Вместо этого я нахожу, что пример откидывания подчеркивает способ jQuery для получения данных в DOMего (потрясающий) Multiview (пользовательский интерфейс), который не требует jQuery, но требует браузера! Еще примеры
    • ... или упор на его архитектуру в стиле MVC ; включая серверную часть (например, соединения с базой данных)
    • Я, наверное, слишком резок; в конце концов, одна из приятных особенностей pandas - то, как она может легко создавать визуализации; прямо из коробки.
  • js-данные
    • Действительно больше ORM ! Большинство его модулей соответствуют различным данных для хранения вопросов ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), сортировка, фильтрация и т.д.
    • С другой стороны, работа с Node.js является приоритетной; «Работает в Node.js и в браузере».
  • мисо (еще одно предложение Руфуса )
    • Впечатляющие бэкеры, такие как Guardian и bocoup .
  • AlaSQL
    • «AlaSQL» - это база данных SQL с открытым исходным кодом для Javascript, в которой особое внимание уделяется скорости запросов и гибкости источников данных как для реляционных данных, так и для данных без схемы. Он работает в вашем браузере, Node.js и Cordova. "
  • Некоторые мысленные эксперименты:

Я надеюсь, что этот пост может стать вики-сообществом и оценивать (то есть сравнивать различные варианты выше) по различным критериям, таким как:

  • Критерии Panda в сравнении с R
    • Производительность
    • Функциональность / гибкость
    • Легкость использования
  • Мои собственные предложения
    • Сходство с API Pandas / Dataframe
    • В частности, об их основных характеристиках
    • Акцент на науку о данных> Акцент на UI
    • Продемонстрированная интеграция в сочетании с другими инструментами, такими как Jupyter (интерактивные записные книжки) и т. Д.

Некоторые вещи, которые JS-библиотека может никогда не выполнять (но может ли?)

  • Использовать базовую структуру, которая является лучшей в своем классе библиотекой чисел / математики Javascript? (т.е. эквивалент NumPy )
  • Используйте любые оптимизирующие / компиляторы, которые могут привести к более быстрому коду (то есть эквивалент использования Pandas Cython )
  • При поддержке любых консорциумов, специализирующихся на науке о данных, ala Pandas и NumFocus

1
Спасибо за этот замечательный обзор. Я знаю как использование фреймов данных pandas, так и SQL. Каковы преимущества (и недостатки) использования JS с фреймами данных по сравнению с базой данных JS SQL?
tardis

@molotow, это отличный вопрос, но у меня нет большого опыта работы с базами данных JS SQL (хотя они выглядят круто). В общем, я бы предположил, что подходы, основанные на типах фреймов данных, будут поддерживать больше функций, ориентированных на "обработку данных" / "науку о данных", например, вывод пустых значений; умножение матриц и т. д. В то время как (JS) SQL больше ориентирован на реляционные вещи: запросы, сортировку, фильтрацию. Конечно, совпадения будут; dataframe может ПРИСОЕДИНЯТЬСЯ, сортировать и фильтровать, точно так же, как SQL включает некоторые статистические функции и т. д. У кого-нибудь еще есть идеи?
The Red Pea

1
раздражает то, что существует так много вариантов. Лучше пусть сообщество сосредоточится только на чем-то одном и сделает это хорошо.
Claudiu Creanga

3
(Автор Arrow JS здесь) @ClaudiuCreanga Я понимаю разочарование. Первоначально мы написали ArrowJS в попытке преодолеть разрыв между узлами / браузерами и более традиционными стеками больших данных, и до сих пор мы вложили самые большие средства в отличные примитивы IPC / потоковой передачи. В качестве следующих шагов мы хотели бы начать интеграцию с другими библиотеками JS (tensorflow, d3 и т. Д.), И PR всегда приветствуются. Альтернативный подход - это такие вещи, как проект JPMC Perspective , который использует ArrowJS для использования и создания таблиц Arrow.
ptaylor

1
есть ли функция для слияния фреймов данных в эквиваленте pandas в javascript?
Phani vikranth

9

Я работал над библиотекой обработки данных для JavaScript под названием data-forge. Он вдохновлен LINQ и Pandas.

Его можно установить так:

npm install --save data-forge

Ваш пример будет работать так:

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

Если ваши данные были в CSV-файле, вы можете загрузить их следующим образом:

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

Вы можете использовать этот selectметод для преобразования строк.

Вы можете извлечь столбец, используя getSeriesзатем этот selectметод для преобразования значений в этом столбце.

Вы получаете свои данные обратно из фрейма данных следующим образом:

var data = dataFrame.toArray();

Чтобы усреднить столбец:

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

С этим можно сделать гораздо больше.

Вы можете найти больше документации на npm .


7

Ceaveat Следующее применимо только к d3 v3, но не к последней версии d4v4!

Я неравнодушен к d3.js , и, хотя он не будет полной заменой Pandas, если вы потратите некоторое время на изучение его парадигмы, он сможет позаботиться обо всех ваших проблемах с данными за вас. (И если вам захочется отображать результаты в браузере, он идеально подходит для этого.)

Пример. Мой файл CSV data.csv:

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

В том же каталоге создайте файл, index.htmlсодержащий следующее:

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

а также demo.jsфайл, содержащий следующее:

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

В каталоге запустите python -m SimpleHTTPServer 8181и откройте http: // localhost: 8181 в своем браузере, чтобы увидеть простой список возрастов и их средний возраст.

Этот простой пример показывает несколько важных функций d3:

  • Отличная поддержка приема онлайн-данных ( CSV , TSV, JSON и т. Д.)
  • Интеллектуальные технологии обработки данных
  • Управляемая данными манипуляция с DOM (возможно, самое сложное для понимания): ваши данные преобразуются в элементы DOM.

2
просто чтобы помочь будущим новичкам - приведенные выше инструкции больше не действуют для d3 v4. думаю, что этап сопоставления теперь выполняется в
обратном вызове

@swyx спасибо за внимание, можете ли вы исправить пример и опубликовать ответ?
Ахмед Фасих

@AhmedFasih Вы должны исправить свой пост на благо всех. Кроме того, у swyx недостаточно репутации для редактирования вашего сообщения.
Carles Alcolea

@CarlesAlcolea Я добавил большой отказ от ответственности вверху, извините, у меня нет времени, чтобы разобраться в текущем API прямо сейчас 😿
Ахмед Фасих

@AhmedFasih ну это лучше, чем раньше :) Спасибо!
Carles Alcolea,

5

Pandas.js на данный момент является экспериментальной библиотекой, но кажется очень многообещающей, она использует под капотом immutable.js и логику NumpPy, есть как серия объектов данных, так и DataFrame.


3
Похоже, что библиотека не фиксировалась более двух лет и, похоже, имеет много проблем. Я бы не сказал «очень многообещающий».
jarthur

4

Ниже Python numpy и 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)

``

То же самое можно сделать в JavaScript * [ numjs работает только с Node.js ] Но D3.js имеет много расширенных параметров набора файлов данных. И numjs, и Pandas-js все еще работают ..

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

*/


3

Я думаю, что наиболее близкими являются такие библиотеки, как:

В частности, у Recline есть объект Dataset со структурой, отчасти похожей на фреймы данных Pandas. Затем он позволяет вам соединять ваши данные с «представлениями», такими как сетка данных, графики, карты и т. Д. Представления обычно представляют собой тонкую оболочку существующих лучших в своем классе библиотек визуализации, таких как D3, Flot, SlickGrid и т. Д.

Вот пример для Recline:

// Загружаем данные
var dataset = recline.Model.Dataset ({
  записи: [
    {значение: 1, дата: '2012-08-07'},
    {value: 5, b: '2013-09-07'}
  ]
  // Вместо этого загружаем данные CSV
  // (И Recline поддерживает гораздо больше типов источников данных)
  // URL: 'my-local-csv-file.csv',
  // бэкэнд: 'csv'
});

// получаем элемент из вашего HTML для зрителя
var $ el = $ ('# просмотрщик данных');

var allInOneDataViewer = новое откидывание.View.MultiView ({
  модель: набор данных,
  el: $ el
});
// Ваш новый просмотрщик данных будет доступен!

3

@neversaint ваше ожидание окончено. скажите, что добро пожаловать в Danfo.js, который представляет собой pandas, подобную библиотеке Javascript, построенную на tensorflow.js и поддерживающую тензоры из коробки. Это означает, что вы можете преобразовать структуру данных danfo в тензоры. И вы можете выполнять группировку, объединение, объединение, построение графиков и другую обработку данных.


1

Анализировать CSV в javascript довольно просто, потому что каждая строка уже представляет собой массив javascript. Если вы загружаете свой csv в массив строк (по одной на строку), довольно легко загрузить массив массивов со значениями:

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

Затем getData()возвращает многомерный массив значений по столбцу.

Я продемонстрировал вам это в jsFiddle .

Конечно, вы не сможете сделать это так легко, если не доверяете вводимым данным - если в ваших данных может быть скрипт, который может подобрать eval и т. Д.


Я знаю, что вы сделали предупреждение в своем ответе, но я действительно не могу не подчеркнуть, насколько плох этот метод с точки зрения безопасности.
xApple

Плохо только с точки зрения безопасности, если он не доверяет входным данным. Если, например, он выполняет школьный проект, в котором он уже знает свои входные файлы (потому что он или его учитель заранее предоставил их в определенном формате), это компактное, простое и разборчивое решение. Он не дал никакого контекста относительно источника своих входных данных, просто попросил способ прочитать CSV для облегчения обработки.
Стив К.

1

Вот динамический подход, предполагающий наличие заголовка в строке 1. CSV загружается с 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);         

});

Затем вы можете получить доступ к каждому столбцу данных, аналогичному фрейму данных R, python или Matlab df.column_header[row_number].

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.