相当于JavaScript中的Python Pandas


90

使用此CSV示例:

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

我使用Pandas的标准方法是:

  1. 解析CSV

  2. 选择数据框中的列(col1col3

  3. 处理列(例如,将col1和的值平均化 col3

是否有一个像Pandas这样的JavaScript库?


5
让我们知道您最终打算做什么。对于我们许多人来说,这是一个重要的问题。
艾哈迈德·法西

Answers:


125

所有答案都很好。希望我的答案是全面的(即尝试列出所有选项)。我希望以任何标准返回并修改此答案,以帮助做出选择。

希望有人来这里熟悉d3d3在处理Javascript中的数据时非常有用的“瑞士军刀”,例如pandas对Python很有帮助。您可能会看到d3经常使用像pandas,即使d3不完全是一个数据帧/大熊猫更换(即d3不具有相同的API;d3没有Series/DataFrame其行为类似于pandas

艾哈迈德(Ahmed)的答案解释了如何使用d3 来实现某些DataFrame功能,并且以下某些库的灵感来自使用和的LearnJsData之类的东西。d3lodash

至于以DataFrame为重点的功能,我不知所措,这对JS库很有帮助。这是您可能遇到的一些选项的快速列表。我尚未详细检查其中的任何一项(大多数是在Google + NPM搜索中找到的)。

请谨慎使用可以使用的各种工具;有些是Node.js(又名服务器端Javascript),有些是与浏览器兼容的又名客户端Javascript。有些是打字稿。

  • 熊猫js
    • STEELFeras的答案
    • “ pandas.js是模仿Python pandas库的开源(实验)库。它依赖Immutable.js作为NumPy逻辑等效项。pandas.js中的主要数据对象与Python pandas中的Series和DataFrame一样。 。”
  • 数据框
    • “ DataFrame-js为JavaScript和数据科学提供了一个不变的数据结构,即DataFrame,它允许使用sql和受函数编程启发的api处理行和列。”
  • 数据伪造
  • jsdataframe
    • “ Jsdataframe是一个JavaScript数据整理库,其灵感来自R和Python Pandas中的数据框功能。”
  • 数据框
    • “通过分组和归约来探索数据。”

然后来到这个问题,在这里检查其他答案并进行更多搜索之后,我发现了类似的选项:

  • JS中的Apache Arrow
    • 感谢用户Back2Basics的建议:
    • “ Apache Arrow是用于对平面和嵌套数据的矢量和表状容器进行编码的列式内存布局规范。ApacheArrow是大型内存列式数据(Spark,Pandas,Drill,Graphistry等)的新兴标准。”
  • 可观察的
    • 乍一看,它似乎JS是IPython / Jupyter “笔记本”的替代品
    • Observable的页面承诺:“ Web平台”上的“响应式编程”,“社区”
    • 在这里看到5分钟的介绍
  • 斜倚(来自Rufus的回答
    • 我期望重点是DataFrame的API,Pandas本身试图 从R保留 记录其对每个R功能的替换/改进/对应
    • 相反,我发现强调斜倚的例子强调 将数据导入DOM的jQuery方法它的(很棒的)Multiview(UI),它不需要jQuery但需要浏览器!更多例子
    • ...或强调其MVC架构;包括后端内容(即数据库连接)
    • 我可能太苛刻了;毕竟,关于熊猫的一件好事是如何轻松创建可视化对象。盒子外面。
  • js数据
    • 真的更多的是ORM!大多数的它的模块对应于不同的数据存储问题(js-data-mongodbjs-data-redisjs-data-cloud-datastore),排序,过滤等
    • 从正面来看,Node.js可以作为第一优先级工作;“在Node.js和浏览器中工作。”
  • Rufus的另一个建议)
  • AlaSQL
    • “ AlaSQL”是用于Javascript的开放源SQL数据库,特别关注关系数据和无模式数据的查询速度和数据源灵活性。它可以在您的浏览器,Node.js和Cordova中使用。”
  • 一些思想实验:

我希望这篇文章可以成为社区Wiki,并根据以下不同标准进行评估(即比较上述不同选项):

  • 熊猫在R比较中的标准
    • 性能
    • 功能/灵活性
    • 便于使用
  • 我自己的建议
    • 与Pandas / Dataframe API的相似性
    • 重点介绍其主要功能
    • 数据科学重点> UI重点
    • 展示了与其他工具Jupyter (如交互式笔记本电脑)等的集成

JS库可能无法做的某些事情(但是可以吗?)


1
感谢您的精彩概述。我知道熊猫数据框和SQL的使用。使用JS和数据数据库使用JS与使用JS SQL数据库有什么优缺点?
tardis

@molotow这是一个很好的问题,但是我对JS SQL数据库没有太多经验(尽管它们看起来很酷)。总的来说,我猜想数据框类型的方法将支持更多以“数据争用” /“数据科学”为重点的功能,例如推断空值。(JS)SQL更着重于关系方面:查询,排序和过滤。当然会有重叠。数据框可以进行JOIN,排序和筛选,就像SQL包含一些统计函数等一样。还有其他人有想法吗?
红豌豆

1
有这么多选择的事实令人讨厌。而是让社区只专注于一件事情并使之变得更好。
Claudiu Creanga

3
(这里是箭头JS作者)@ClaudiuCreanga我理解沮丧。最初,我们编写ArrowJS的目的是弥合节点/浏览器与更传统的大数据堆栈之间的鸿沟,到目前为止,我们已经在出色的IPC /流原始数据上投入了最大的精力。下一步,我们很乐意开始与更多JS库(tensorflow,d3等)集成,并且始终欢迎PR。另一种替代方法是JPMC的Perspective项目,该项目使用ArrowJS消费和产生Arrow表。
泰勒(Ptaylor)

1
javascript中的pandas中的dataframe合并功能是否存在?
Phani vikranth '19

9

我一直在研究JavaScript的数据处理库,称为数据伪造。它受到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上找到更多文档。


6

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不再有效。认为映射阶段现在在数据回调中完成,例如github.com/d3/d3-dsv/blob/master/README.md#csvParseRows
swyx

@swyx感谢您的注意,您可以更正示例并发布为答案吗?
艾哈迈德·法西

@AhmedFasih为了所有人的利益,您应该更正自己的帖子。另外,swyx没有足够的声誉来编辑您的帖子。
卡尔斯·阿尔科里亚

@CarlesAlcolea我在上面画了一个大大的免责声明,对不起,我没有时间起床速度对当前API现在😿
艾哈迈德Fasih

@AhmedFasih好吧,这比以前要好:)谢谢!
卡尔斯·阿尔科利亚

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({
  记录: [
    {value:1,date:'2012-08-07'},
    {值:5,b:'2013-09-07'}
  ]
  //而是加载CSV数据
  //(并且Recline支持更多的数据源类型)
  //网址:“ my-local-csv-file.csv”,
  //后端:“ csv”
});

//从HTML中为查看器获取一个元素
var $ el = $('#data-viewer');

var allInOneDataViewer = new recline.View.MultiView({
  型号:数据集,
  埃尔:$ el
});
//您的新数据查看器将上线!

3

@neversaint您的等待结束。对Danfo.js表示欢迎,它是像tensorflow.js上构建的Javascript库之类的熊猫,并支持开箱即用。这意味着您可以将danfo数据结构转换为张量。您可以进行分组,合并,合并,绘图和其他数据处理。


1

在javascript中解析CSV很容易,因为每一行实际上已经是一个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的方法以便于处理。
史蒂夫·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]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.