Еквівалент 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
    • З сталевих і Feras відповіді "
    • "pandas.js - це відкрита (експериментальна) бібліотека, що імітує бібліотеку панд Python. Вона покладається на Immutable.js як логічний еквівалент NumPy. Основними об'єктами даних у pandas.js є, як і в пандах Python, Series і DataFrame . "
  • dataframe-js
    • "DataFrame-js забезпечує незмінну структуру даних для javascript та datascience, DataFrame, яка дозволяє працювати над рядками та стовпцями за допомогою sql та API, натхненного функціональним програмуванням."
  • підробка даних
    • У відповіді Ешлі Девіс
    • "Набір інструментів для перетворення та аналізу даних JavaScript натхненний Pandas та LINQ."
    • Зверніть увагу, що старе сховище даних forge JS більше не підтримується; тепер нове сховище використовує Typescript
  • jsdataframe
    • "Jsdataframe - це бібліотека для переміщення даних JavaScript, натхненна функціональністю фреймів даних у R і Python Pandas."
  • фрейм даних
    • "досліджувати дані, групуючи та зменшуючи."

Потім, прийшовши до цього питання, перевіривши тут інші відповіді та зробивши додатковий пошук, я знайшов такі варіанти:

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

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

  • Критерії Панди при її порівнянні R
    • Продуктивність
    • Функціональність / гнучкість
    • Простота використання
  • Мої власні пропозиції
    • Подібність до API Pandas / Dataframe
    • Конкретно вражає їх основні особливості
    • Наголос на науці про дані> Підкреслення інтерфейсу користувача
    • Продемонстрована інтеграція в поєднанні з іншими інструментами, такими як Jupyter (інтерактивні блокноти) тощо

Деякі речі, які бібліотека JS може ніколи не робити (але чи не могла?)


1
Дякуємо за цей чудовий огляд. Я знаю як використання фреймів даних pandas, так і SQL. Які переваги (та недоліки) використання JS з використанням фреймів даних у порівнянні з базою даних JS SQL?
тардіс

@molotow це чудове питання, але я не маю великого досвіду роботи з базами даних JS SQL (хоча вони виглядають круто). Загалом, я вважаю, що підходи типу фреймів даних підтримували б більше функцій, спрямованих на "переміщення даних" / "наука про дані", як виведення порожніх значень; робить множення матриць тощо. Тоді як (JS) SQL більше орієнтований на реляційні речі: запити, сортування, фільтрування. Звичайно, буде перекриття; фрейм даних може ПРИЄДНАТИСЯ, сортувати та фільтрувати, подібно до того, як SQL включає деякі статистичні функції тощо. Хтось ще має ідеї?
The Red Pea

1
той факт, що варіантів так багато, дратує. Скоріше, щоб громада зосередилася лише на одній справі та зробила це корисним.
Клаудіу Креанга

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

1
чи існує функціонал для злиття фреймів даних у еквівалентних пандах у 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

Наведене нижче стосується лише 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. вважаю, що етап відображення виконано в рамках зворотного виклику даних, наприклад, github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx

@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 набір даних = recline.Model.Dataset ({
  записів: [
    {значення: 1, дата: '2012-08-07'},
    {значення: 5, b: '07.09.2013'}
  ]
  // Замість цього завантажуємо дані CSV
  // (А Recline має підтримку для багатьох інших типів джерел даних)
  // url: 'my-local-csv-file.csv',
  // бекенд: 'csv'
});

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

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

3

@neversaint ваші очікування закінчилися. скажіть ласкаво просимо до Danfo.js, який є пандами, як бібліотека 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 для зручності обробки.
Steve K

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.