Python Pandas tương đương trong JavaScript


91

Với ví dụ CSV này:

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

Phương pháp tiêu chuẩn mà tôi sử dụng Pandas là:

  1. Phân tích cú pháp CSV

  2. Chọn các cột vào khung dữ liệu ( col1col3)

  3. Xử lý cột (ví dụ: trung bình các giá trị của col1col3)

Có thư viện JavaScript nào làm được điều đó như Pandas không?


5
Hãy cho chúng tôi biết những gì bạn gặp phải. Đây là một câu hỏi quan trọng đối với nhiều người trong chúng ta.
Ahmed Fasih

Câu trả lời:


126

Tất cả các câu trả lời đều tốt. Hy vọng câu trả lời của tôi là toàn diện (tức là cố gắng liệt kê tất cả các tùy chọn). Tôi hy vọng sẽ quay lại và sửa đổi câu trả lời này với bất kỳ tiêu chí nào để giúp đưa ra lựa chọn.

Tôi hy vọng bất cứ ai đến đây đều quen thuộc d3. d3là "con dao quân đội Thụy Sĩ" rất hữu ích để xử lý dữ liệu trong Javascript, giống như pandasrất hữu ích cho Python. Bạn có thể thấy d3sử dụng thường xuyên như pandas, ngay cả khi d3không chính xác một sự thay thế DataFrame / Pandas (tức là d3không có các API cùng; d3không có Series/ DataFramemà cư xử như thế nào trong pandas)

Câu trả lời của Ahmed giải thích cách d3 có thể được sử dụng để đạt được một số chức năng DataFrame và một số thư viện bên dưới được lấy cảm hứng từ những thứ như LearnJsData sử dụng d3lodash.

Đối với các tính năng tập trung vào DataFrame, tôi đã bị choáng ngợp với các thư viện JS giúp ích. Dưới đây là danh sách nhanh một số tùy chọn mà bạn có thể gặp phải. Tôi chưa kiểm tra chi tiết bất kỳ thông tin nào (Hầu hết tôi tìm thấy trong kết hợp tìm kiếm Google + NPM).

Hãy cẩn thận, bạn sử dụng nhiều loại mà bạn có thể làm việc với; một số là Node.js hay còn gọi là Javascript phía máy chủ, một số là Javascript phía máy khách tương thích với trình duyệt. Một số là chữ gõ.

  • gấu trúc-js
    • Từ câu trả lời của STEELFeras
    • "pandas.js là một thư viện mã nguồn mở (thử nghiệm) bắt chước thư viện gấu trúc Python. Nó dựa vào Immutable.js làm tương đương logic NumPy. Các đối tượng dữ liệu chính trong pandas.js giống như trong Python pandas, Series và DataFrame . "
  • dataframe-js
    • "DataFrame-js cung cấp cấu trúc dữ liệu bất biến cho javascript và khoa học dữ liệu, DataFrame, cho phép làm việc trên các hàng và cột với api lấy cảm hứng từ lập trình sql và chức năng."
  • dữ liệu giả mạo
  • jsdataframe
    • "Jsdataframe là một thư viện bao bọc dữ liệu JavaScript được lấy cảm hứng từ chức năng khung dữ liệu trong R và Python Pandas."
  • khung dữ liệu
    • "khám phá dữ liệu bằng cách nhóm và giảm."

Sau đó, sau khi đến câu hỏi này, kiểm tra các câu trả lời khác tại đây và thực hiện thêm tìm kiếm, tôi đã tìm thấy các tùy chọn như:

  • Apache Arrow trong JS
    • Cảm ơn đề xuất Back2Basics của người dùng:
    • "Apache Arrow là đặc điểm kỹ thuật bố trí bộ nhớ dạng cột để mã hóa vectơ và vùng chứa dạng bảng của dữ liệu phẳng và lồng nhau. Apache Arrow là tiêu chuẩn mới nổi cho dữ liệu dạng cột lớn trong bộ nhớ (Spark, Pandas , Drill, Graphistry, ...)"
  • Có thể quan sát được
    • Thoạt nhìn, có vẻ như một JSsự thay thế cho "máy tính xách tay" IPython / Jupyter
    • Trang của Observable hứa hẹn: "Lập trình phản ứng", một "Cộng đồng", trên "Nền tảng web"
    • Xem 5 phút giới thiệu tại đây
  • ngả lưng (từ câu trả lời của Rufus )
    • Tôi mong đợi sự nhấn mạnh vào API của DataFrame, mà bản thân Pandas cố gắng bảo tồn từ R tài liệu thay thế của nó / cải thiện / thư đến từng chức năng R .
    • Thay vào đó, tôi thấy ví dụ của dòng nhấn mạnh nhấn mạnh cách jQuery lấy dữ liệu vào DOMMultiview (tuyệt vời) của nó (giao diện người dùng), không yêu cầu jQuery nhưng yêu cầu trình duyệt! Các ví dụ khác
    • ... hoặc nhấn mạnh vào kiến trúc MVC-ish của nó ; bao gồm cả nội dung back-end (tức là kết nối cơ sở dữ liệu)
    • Tôi có lẽ đang quá khắc nghiệt; xét cho cùng, một trong những điều thú vị về gấu trúc là cách nó có thể tạo ra những hình dung dễ dàng; ngoài cái hộp.
  • dữ liệu js
    • Thực sự nhiều hơn một ORM ! Hầu hết các module của nó tương ứng với dữ liệu khác nhau lưu trữ câu hỏi ( js-data-mongodb, js-data-redis, js-data-cloud-datastore), phân loại, lọc vv
    • Về phía cộng, hoạt động trên Node.js là ưu tiên hàng đầu; "Hoạt động trong Node.js và trong Trình duyệt."
  • miso (một gợi ý khác từ Rufus )
    • Những người ủng hộ ấn tượng như Guardianbocoup .
  • AlaSQL
    • "AlaSQL" là cơ sở dữ liệu SQL mã nguồn mở cho Javascript tập trung mạnh vào tốc độ truy vấn và tính linh hoạt của nguồn dữ liệu cho cả dữ liệu quan hệ và dữ liệu không toán học. Nó hoạt động trong trình duyệt của bạn, Node.js và Cordova. "
  • Một số thí nghiệm suy nghĩ:

Tôi hy vọng bài đăng này có thể trở thành wiki cộng đồng và đánh giá (tức là so sánh các tùy chọn khác nhau ở trên) dựa trên các tiêu chí khác nhau như:

  • Các tiêu chí của Panda trong so sánh R của nó
    • Hiệu suất
    • Chức năng / tính linh hoạt
    • Dễ sử dụng
  • Đề xuất của riêng tôi
    • Tương tự với API của Pandas / Dataframe
    • Cụ thể là đánh vào các tính năng chính của chúng
    • Nhấn mạnh khoa học dữ liệu> nhấn mạnh giao diện người dùng
    • Tích hợp được chứng minh kết hợp với các công cụ khác như Jupyter (sổ ghi chép tương tác), v.v.

Một số điều mà thư viện JS có thể không bao giờ làm (nhưng có thể không?)

  • Sử dụng một khung cơ bản là thư viện toán / số Javascript tốt nhất trong lớp? (tức là tương đương với NumPy )
  • Sử dụng bất kỳ trình biên dịch / tối ưu hóa nào có thể dẫn đến mã nhanh hơn (tức là tương đương với việc sử dụng Cython của Pandas )
  • Được tài trợ bởi bất kỳ hiệp hội có hương vị khoa học dữ liệu nào, ala Pandas và NumFocus

1
Cảm ơn về tổng quan tuyệt vời này. Tôi biết cả việc sử dụng khung dữ liệu gấu trúc và SQL. Ưu điểm (và nhược điểm) của việc sử dụng JS bằng khung dữ liệu so với cơ sở dữ liệu JS SQL là gì?
tardis

@molotow đây là một câu hỏi tuyệt vời, nhưng tôi không có nhiều kinh nghiệm với cơ sở dữ liệu JS SQL (mặc dù chúng trông rất tuyệt). Nói chung, tôi đoán rằng các phương pháp tiếp cận kiểu khung dữ liệu sẽ hỗ trợ nhiều hàm tập trung "data wrangling" / "data-science" hơn, như suy ra các giá trị trống; thực hiện phép nhân ma trận, v.v. Trong khi SQL (JS) tập trung nhiều hơn vào các nội dung quan hệ: truy vấn, sắp xếp, lọc. Tất nhiên sẽ có sự chồng chéo; dataframe có thể THAM GIA, sắp xếp và lọc, giống như SQL bao gồm một số chức năng thống kê và v.v. Có ai khác có ý tưởng không?
The Red Pea,

1
thực tế là có quá nhiều lựa chọn gây khó chịu. Thay vì cộng đồng chỉ tập trung vào một thứ và làm cho nó tốt.
Claudiu Creanga

3
(Tác giả của Arrow JS ở đây) @ClaudiuCreanga Tôi hiểu sự thất vọng. Ban đầu, chúng tôi viết ArrowJS trong một nỗ lực nhằm thu hẹp khoảng cách giữa nút / trình duyệt và các ngăn xếp dữ liệu lớn truyền thống hơn và cho đến nay chúng tôi đã đầu tư rất nhiều vào các nguyên thủy IPC / phát trực tuyến tuyệt vời. Trong các bước tiếp theo, chúng tôi muốn bắt đầu tích hợp với nhiều JS lib hơn (tensorflow, d3, v.v.) và PR luôn được hoan nghênh. Một cách tiếp cận thay thế là những thứ như dự án Quan điểm của JPMC , sử dụng ArrowJS để sử dụng và sản xuất các bảng Arrow.
ptaylor

1
có chức năng nào để hợp nhất khung dữ liệu trong pandas tương đương trong javascript không?
Phani vikranth

9

Tôi đang làm việc trên một thư viện quấn dữ liệu cho JavaScript có tên là data-forge. Nó được lấy cảm hứng từ LINQ và Pandas.

Nó có thể được cài đặt như thế này:

npm install --save data-forge

Ví dụ của bạn sẽ hoạt động như thế này:

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

Nếu dữ liệu của bạn ở trong tệp CSV, bạn có thể tải nó như sau:

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

Bạn có thể sử dụng selectphương pháp này để biến đổi hàng.

Bạn có thể trích xuất một cột bằng cách sử dụng getSeriessau đó sử dụng selectphương pháp để chuyển đổi các giá trị trong cột đó.

Bạn lấy lại dữ liệu của mình ra khỏi khung dữ liệu như sau:

var data = dataFrame.toArray();

Để tính trung bình một cột:

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

Bạn có thể làm được nhiều hơn thế với điều này.

Bạn có thể tìm thêm tài liệu về npm .


7

Ceaveat Những điều sau chỉ áp dụng cho d3 v3 và không áp dụng cho d4v4 mới nhất!

Tôi là một phần của d3.js và mặc dù nó sẽ không phải là sự thay thế hoàn toàn cho Pandas, nhưng nếu bạn dành một chút thời gian để tìm hiểu mô hình của nó, nó sẽ có thể xử lý tất cả dữ liệu của bạn đang lộn xộn cho bạn. (Và nếu bạn muốn hiển thị kết quả trong trình duyệt, nó lý tưởng cho việc đó.)

Thí dụ. Tệp CSV của tôi data.csv:

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

Trong cùng một thư mục, hãy tạo một thư index.htmlmục sau:

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

và cả một demo.jstệp chứa những thứ sau:

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

Trong thư mục, hãy chạy python -m SimpleHTTPServer 8181và mở http: // localhost: 8181 trong trình duyệt của bạn để xem danh sách đơn giản về độ tuổi và mức trung bình của chúng.

Ví dụ đơn giản này cho thấy một vài tính năng có liên quan của d3:

  • Hỗ trợ tuyệt vời cho việc nhập dữ liệu trực tuyến ( CSV , TSV, JSON, v.v.)
  • Dữ liệu bao bọc thông minh được đưa vào
  • Thao tác DOM theo hướng dữ liệu (có thể là điều khó khăn nhất để quấn lấy đầu người ta): dữ liệu của bạn được chuyển đổi thành các phần tử DOM.

2
chỉ để giúp những người mới trong tương lai - hướng dẫn trên không còn hợp lệ cho d3 v4. nghĩ giai đoạn lập bản đồ được thực hiện trong dữ liệu gọi lại tại ví dụ github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
Swyx

@swyx cảm ơn bạn đã lưu ý, bạn có thể sửa ví dụ và đăng dưới dạng câu trả lời được không?
Ahmed Fasih 29/12/16

@AhmedFasih Bạn nên sửa lại bài đăng của mình vì lợi ích của mọi người. Ngoài ra, swyx không có đủ danh tiếng để chỉnh sửa bài đăng của bạn.
Carles Alcolea

@CarlesAlcolea Tôi đã thêm một từ chối trách nhiệm lớn ở phía trên, xin lỗi tôi không có thời gian để có được lên đến tốc độ trên API hiện ngay bây giờ 😿
Ahmed Fasih

@AhmedFasih tốt hơn trước :) Cảm ơn!
Carles Alcolea

5

Pandas.js tại thời điểm hiện tại là một thư viện thử nghiệm, nhưng có vẻ rất hứa hẹn nó sử dụng theo logic Immutable.js và NumpPy, cả chuỗi đối tượng dữ liệu và DataFrame đều ở đó ..


3
Có vẻ như thư viện đã không có cam kết trong hơn hai năm và dường như có nhiều vấn đề. Tôi sẽ không nói 'rất hứa hẹn'.
jarthur

4

Dưới đây là Python numpy và gấu trúc

``

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)

``

Điều tương tự cũng có thể đạt được trong JavaScript * [ numjs chỉ hoạt động với Node.js ] Nhưng D3.js có nhiều tùy chọn tập hợp tệp Dữ liệu nâng cao. Cả numjs và Pandas-js vẫn đang hoạt động ..

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

Tôi nghĩ điều gần nhất là các thư viện như:

Đặc biệt, Recline có một đối tượng Dataset với cấu trúc hơi giống với các khung dữ liệu Pandas. Sau đó, nó cho phép bạn kết nối dữ liệu của mình với "Chế độ xem" chẳng hạn như lưới dữ liệu, vẽ đồ thị, bản đồ, v.v. Chế độ xem thường là những lớp bọc mỏng xung quanh các thư viện hình ảnh giống tốt nhất hiện có như D3, Flot, SlickGrid, v.v.

Đây là một ví dụ cho Recline:

// Tải một số dữ liệu
var dataset = recline.Model.Dataset ({
  Hồ sơ: [
    {value: 1, date: '2012-08-07'},
    {value: 5, b: '2013-09-07'}
  ]
  // Tải dữ liệu CSV thay thế
  // (Và Recline có hỗ trợ nhiều kiểu nguồn dữ liệu khác)
  // url: 'my-local-csv-file.csv',
  // phụ trợ: 'csv'
});

// lấy một phần tử từ HTML của bạn cho người xem
var $ el = $ ('# data-viewer');

var allInOneDataViewer = new recline.View.MultiView ({
  mô hình: tập dữ liệu,
  el: $ el
});
// Trình xem dữ liệu mới của bạn sẽ hoạt động!

3

@neversaint sự chờ đợi của bạn đã kết thúc. chào mừng bạn đến với Danfo.js , một thư viện giống như thư viện Javascript được xây dựng trên tensorflow.js và hỗ trợ tensor ra khỏi hộp. Điều này có nghĩa là bạn có thể chuyển đổi cấu trúc dữ liệu danfo sang Tensors. Và bạn có thể thực hiện theo nhóm, hợp nhất, tham gia, vẽ và xử lý dữ liệu khác.


1

Khá dễ dàng để phân tích cú pháp CSV trong javascript vì mỗi dòng về cơ bản đã là một mảng javascript. Nếu bạn tải csv của mình vào một mảng chuỗi (một chuỗi trên mỗi dòng) thì khá dễ dàng để tải một mảng mảng với các giá trị:

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

Sau đó, getData()trả về một mảng giá trị nhiều chiều theo cột.

Tôi đã chứng minh điều này trong một jsFiddle cho bạn.

Tất nhiên, bạn không thể làm điều này một cách dễ dàng nếu bạn không tin tưởng đầu vào - nếu có thể có tập lệnh trong dữ liệu của bạn mà eval có thể nhận, v.v.


Tôi biết bạn đã đưa ra một cảnh báo trong câu trả lời của mình, nhưng tôi thực sự không thể nhấn mạnh đủ mức độ tồi tệ của phương pháp này từ quan điểm bảo mật.
xApple

Nó chỉ xấu từ quan điểm bảo mật nếu anh ta không tin tưởng vào đầu vào. Ví dụ: nếu anh ta đang thực hiện một dự án trường học trong đó anh ta đã biết các tệp đầu vào của mình (vì anh ta hoặc giáo viên của anh ta đã cung cấp chúng trước thời hạn ở một định dạng cụ thể), thì đây là một giải pháp nhỏ gọn, dễ dàng và rõ ràng. Anh ấy không đưa ra bất kỳ bối cảnh nào liên quan đến nguồn đầu vào của mình, chỉ yêu cầu cách đọc CSV để dễ dàng xử lý.
Steve K

1

Đây là một cách tiếp cận động giả sử một tiêu đề hiện có trên dòng 1. csv được tải bằng 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);         

});

Sau đó, bạn có thể truy cập từng cột dữ liệu tương tự như khung dữ liệu R, python hoặc Matlab df.column_header[row_number].

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.