Операции с данными (fill, min, max) с данными CSV в JavaScript? - PullRequest
3 голосов
/ 13 августа 2011

Я загружаю разные CSV-файлы индикатора в JavaScript, например:

CSV for population:

id,year,value
AF,1800,3280000
AF,1820,3280000
AF,1870,4207000
AG,1800,37000
AG,1851,37000
AG,1861,37000

Для каждого файла индикатора мне нужно:

  • Заполнить пропущенные годы для каждой сущности (id)
  • Найти временной интервал для каждого объекта
  • Найти минимальное и максимальное значения для каждого объекта
  • Найти временной интервал для индикатора
  • Найти значениеmin и max для индикатора

Какой недорогой способ выполнения этих операций?В качестве альтернативы, есть ли хорошая библиотека JavaScript для выполнения таких общих операций с данными и эффективного хранения данных в различных представлениях объектов?

Я бы хотел, чтобы окончательное представление вышеуказанного файла выглядело примерно так:

data = {
    population : {
        entities : 
            AF : {
                data : {
                    1800 : 3280000,
                    1801 : 3280000,
                 },
                entity_meta : {
                    start : 1800,
                    end : 
                    min : 
                    max :
             },
            [...]
        indicator_meta : {
                start : 1700,
                end : 
                min : 
                max :
        }
        [...]

Спасибо!

Ответы [ 4 ]

2 голосов
/ 22 августа 2011

Давайте предположим, что у вас есть данные CSV в двумерном массиве:

var data = [[AF,1800,3280000],
[AF,1820,3280000],
[AF,1870,4207000],
[AG,1800,37000],
[AG,1851,37000],
[AG,1861,37000]]

В этом примере я буду использовать вспомогательные функции jQuerys, поскольку это значительно облегчит работу без каких-либо дополнительных затрат.

// we will loop thru all the rows
// if the id does not belong to the entities then we will add the property.
// if the property does exist then we update the values

var entities = {}
$.each(data, function (i, n) {

    // set property
    if (!entities[n[0]]) {
        entities[n[0]] = {
            data : {
                n[1]: n[2]
            },
            entity_meta: {
                start: n[1],
                end: n[1]
                min: n[1]
                max: n[1]
            }
        }

    // update property
    } else {

        // add new data property
        entities[n[0]]['data'][n[1]] = n[2];

        // if the property should change then update it
        if ( entities[n[0]]['entity_meta']['min'] > n[1] ) {
             entities[n[0]]['entity_meta']['min'] = n[1];
        }
    }
});

Это, очевидно, не весь код, но он должен четко объяснять подход, который следует использовать.

Также не то, что ваша предполагаемая final структура объекта очень большая более сложный вы должны использовать массивы там, где это необходимо, особенно для entities и data.

1 голос
/ 22 августа 2011

Есть библиотеки баз данных javascript sql. TaffyDB приходит на ум.

1 голос
/ 18 августа 2011

Может быть, YUI будет полезен для некоторых массовых операций. http://yuilibrary.com/yui/docs/dataschema/dataschema-text.html

1 голос
/ 17 августа 2011

Используйте jQuery AJAX для получения файла CSV.

$.get("test_csv.csv", function(result){
    csvParseAndCalc(result);
});

Используйте простой JavaScript для анализа CSV и выполнения вычислений

// assumes your sample data is how all data will look
// proper csv parsing (by the spec) is not used is favor is speed
function csvParseAndCalc(result) {
var entities = {};
var indicator_meta = {"start":null, "end":null, "min":null, "max":null};
var rows = result.split('\n'); //your data doesnt need proper (to spec) csv parsing
// run calculations ignore header row
for(var i=1; i<rows.length; i++) {
    var r = rows[i].split(',');
    var id = r[0];
    var yr = parseInt(r[1]);
    var val = parseInt(r[2]);
    var entity = entities[id];
    var edata;
    var emeta;
    // create entity if it doesn't exist
    if(entity == null) {
        entities[id] = { "data": {}, "entity_meta": {"start":null, "end":null, "min":null, "max":null} };
        entity = entities[id];
    }
    // entity data
    edata = entity.data;
    edata[yr] = val;
    // entity meta
    emeta = entity.entity_meta
    if(emeta.start == null || emeta.start > yr) emeta.start = yr;
    if(emeta.end == null || emeta.end < yr) emeta.end = yr;
    if(emeta.min == null || emeta.min > val) emeta.min = val;
    if(emeta.max == null || emeta.max < val) emeta.max = val;
    // calc indicator_meta
    if(indicator_meta.start==null || indicator_meta.start > yr)
        indicator_meta.start = yr;
    if(indicator_meta.end==null || indicator_meta.end < yr)
        indicator_meta.end = yr;
    if(indicator_meta.min==null || indicator_meta.min > val)
        indicator_meta.min = val;
    if(indicator_meta.max==null || indicator_meta.max < val)
        indicator_meta.max = val;
}
// fill gaps on entity data
for(var id in entities) {
    var entity = entities[id];
    var emeta = entity.entity_meta;
    var edata = entity.data;
    for(var i=emeta.start + 1; i<emeta.end; i++) {
        if(edata[i] == null) edata[i] = edata[i-1];
    }
}
return {"population": {"entities":entities, "indicator_meta":indicator_meta} };
}
...