加载为地图的CSV文件(D3和JavaScript)

时间:2018-09-08 14:00:53

标签: javascript d3.js

我浏览了JavaScript和D3的文档,但找不到任何可以帮助我的东西...

是否可以加载如下所示的CSV文件:

header, header
string1, string
string2, string
...
stringN, string

并存储到Map中?理想情况下使用D3上传的CSV?

d3.csv("demoCSVOne.csv", function(errorOne, one) {
    d3.csv("demoCSVTwo.csv", function(errorTwo, two) {

    // do something

    }
}

CSV示例

String, Integer
one, 2345
two, 34536
three, 24536

对于马克 我正在尝试实现此计算-从已选择的多个CSV中获取平均值。其中a,b,c等表示键的值:

[(a_csv1 + a_csv2 + a_csv3)/3]
[(b_csv1 + b_csv2 + b_csv3)/3]
[(c_csv1 + c_csv2 + c_csv3)/3]

然后将这些平均值存储在一个新数组中,其中包含该平均值表示的键的长度。我的目标是这样:

键,平均      一个123      b,456      c,789

1 个答案:

答案 0 :(得分:3)

这就是我要做的。注意,我只是使用JavaScript对象作为地图,而不是ES6 Map对象。

d3.csv('csv1.csv', function(e1, one) {

  d3.csv('csv2.csv', function(e2, two) {

    // our final map
    var aveMap = {};

    // concat the two csv arrays together
    one.concat(two).map((d) => {
      if (!aveMap[d.String]) aveMap[d.String] = {
        values: []
      };
      // build array of values by key
      aveMap[d.String].values.push(+d.Integer);
    });

    // loop and calculate mean
    Object.keys(aveMap).map((k) => {
      aveMap[k].mean = d3.mean(aveMap[k].values);
    });     

  });
});

产生最终的数据结构为:

{
  "one": {
    "values": [
      2345,
      2323
    ],
    "mean": 2334
  },
  "two": {
    "values": [
      34536,
      45456
    ],
    "mean": 39996
  },
  "three": {
    "values": [
      24536,
      56567
    ],
    "mean": 40551.5
  }
}

看到它运行here

编辑评论

在内存中保留extra values属性并没有真正使此代码变慢。如果性能不佳,则有两个原因:您有很多CSV文件,或者它们是巨大的CSV文件。为了提高性能,我将切换为以下内容:

var q = d3.queue();
['csv1.csv', 'csv2.csv'].map((c) => {
  q.defer(d3.csv, c);
});

q.awaitAll(function(d, csvs){
    var arr = d3.merge(csvs),
        aveMap = {};

    arr.map((d,i) => {
      if (!aveMap[d.String]) {
        aveMap[d.String] = {
          sum: 0,
          count: 0
        };
      }
      var obj = aveMap[d.String];
      obj.sum += +d.Integer;
      obj.count += 1;

      if ( obj.count === csvs.length ){
       obj.mean = obj.sum / obj.count;
      }
    });

    console.log(aveMap);
});

首先,通过使用d3.queue,您将同时下载csv文件,而不是一个接一个地下载。其次,您可以将输入调整为.defer以仅下载用户实际需要的文件。第三,您会注意到我现在正在计算第一个循环内的平均值。如果这些是大型数据集,则希望最小化它们之间的循环。第四,我现在总结。当然,此重构假定每个密钥在每个csv文件中都存在一次。