[英]Loading in a CSV file as a Map (D3 and JavaScript)
我查看了 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]
然后需要將這些平均值存儲在一個新數組中,一個帶有平均值代表的鍵的 long。 我的目標是讓它看起來像這樣:
key, average a, 123 b, 456 c, 789
這是我將如何做到的。 注意,我只是使用了一個 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
}
}
看到它在這里運行。
評論編輯
在內存中保存額外的 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 文件中都存在一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.