我浏览了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
答案 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文件中都存在一次。