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

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

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

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

  • Parse CSV

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

  • Обработать столбец (например, указать значения col1 и col3)

Есть ли библиотека JavaScript, которая делает это как Pandas?

Ответ 1

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

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

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

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

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

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

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

  • Apache Arrow в JS
    • Спасибо пользователю Back2Basics за предложение:
    • "Apache Arrow - это спецификация столбцовой памяти для кодирования векторов и табличных контейнеров плоских и вложенных данных. Apache Arrow - это новый стандарт для больших столбчатых данных в памяти (Spark, Pandas, Drill, Graphistry ,...) "
  • Наблюдаемое
    • На первый взгляд, это JS альтернатива "ноутбукам" IPython/Jupyter "notebooks"
    • Наблюдаемые страницы обещаний: "Реактивное программирование", "Сообщество", на "Веб-платформе"
    • Смотрите 5-минутное вступление здесь
  • откидываться (из ответа Руфуса)
    • Я ожидал акцента на API DataFrame, который сама Pandas пытается сохранить из R документао его замене/улучшении/соответствии каждой функции R.
    • Вместо этого я обнаружил, что пример с откидывающимся акцентом подчеркивает способ jQuery получения данных в DOM его (удивительный) Multiview (UI), который не требует jQuery, но требует браузера! Еще примеры
    • ... или акцент на его архитектуре MVC; включая вспомогательные компоненты (то есть соединения с базой данных)
    • Я, вероятно, слишком резок; в конце концов, одна из приятных вещей в пандах - то, как она может легко создавать визуализации; вне коробки.
    • 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. "
  • Некоторые мысленные эксперименты:

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

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

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

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

Ответ 2

Я работал над библиотекой обработки данных для 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.

Ответ 3

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

Ответ 4

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

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

Вот пример для ссылки:

// Load some data
var dataset = recline.Model.Dataset({
  records: [
    { value: 1, date: '2012-08-07' },
    { value: 5, b: '2013-09-07' }
  ]
  // Load CSV data instead
  // (And Recline has support for many more data source types)
  // url: 'my-local-csv-file.csv',
  // backend: 'csv'
});

// get an element from your HTML for the viewer
var $el = $('#data-viewer');

var allInOneDataViewer = new recline.View.MultiView({
  model: dataset,
  el: $el
});
// Your new Data Viewer will be live!

Ответ 5

Ниже питон numpy и панды

"""

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

*/

Ответ 6

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

Ответ 7

Очень легко разобрать 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 для вас.

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

Ответ 8

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