Загрузка в CSV-файл как карту (D3 и JavaScript)

Я просмотрел документацию по JavaScript и D3, но не нашел ничего, что могло бы мне помочь ...

Можно ли загрузить файл CSV, который выглядит так:

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

И хранить в карта? В идеале, используя загруженный CSV-файл D3?

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]

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

key, average
     a, 123
     b, 456
     c, 789

как насчет применения Array.map()

rioV8 08.09.2018 16:13

Не уверен, как это будет работать с синтаксисом загрузки в CSV ... См. Править

dumbquestionsbydumbpeople 08.09.2018 16:24

Ответ на ваш вопрос, конечно, да, но вы не предоставляете нам достаточно подробностей. Из вашего CSV, каков ваш ключ и какова ваша ценность? Конечно, у вас может быть немного х / у проблема. Если вы работаете в d3, метод .csv создаст массив объектов, и это обычно предпочтительная структура данных.

Mark 08.09.2018 16:29

@Mark Я включил пример того, как выглядят мои файлы CSV. Файлы CSV поступают из HashMap в Java, поэтому ключи остаются одинаковыми для каждого создаваемого файла CSV, меняются только значения. После загрузки файлов CSV в D3 я хочу взять их содержимое и усреднить значения каждого из файлов CSV по всем измерениям карты (ключи). С этими новыми средними значениями, перенесенными на новую карту, связанную с ключами, которые они усредняли.

dumbquestionsbydumbpeople 08.09.2018 16:35
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
1 455
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот как бы я это сделал. Обратите внимание: я просто использовал объект 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
  }
}

Посмотрите, как он работает здесь.

Редактирование комментариев

Хранение свойства дополнительных значений в памяти на самом деле не замедляет этот код. Если он неэффективен, есть две причины: у вас много файлов 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.info(aveMap);
});

Во-первых, используя d3.queue, вы загружаете файлы csv одновременно, а не выполняете их один за другим. Во-вторых, вы можете настроить ввод .defer, чтобы загружать только те файлы, которые действительно нужны пользователю. В-третьих, вы заметите, что теперь я вычисляю среднее значение внутри первого цикла. Если это большие наборы данных, вы хотите свести к минимуму зацикливание по ним. В-четвертых, я сейчас подхожу к подведению итогов. Конечно, этот повторный фактор предполагает, что каждый ключ существует в каждом файле CSV один раз.

Хорошо, это интересный подход. Несколько вещей: эти два CSV были просто примером, CSV, которые будут использоваться, будут зависеть от того, какие точки данных выберет пользователь. Итак, есть ли способ сделать функцию .concat динамической? Иногда пользователь может выбрать один, два, три и т. д. CSV. Возможно ли также, чтобы средняя карта содержала только ключи и средние значения? После игры с ним в консоли он очень медленный, и все, что мне нужно, это ключи и их новые значения.

dumbquestionsbydumbpeople 08.09.2018 17:54

Потрясающе, отлично выглядит и имеет для меня больше смысла. Я просто попробовал это с 6 файлами CSV, и загрузка данных занимает много времени, но работает отлично. Спасибо.

dumbquestionsbydumbpeople 08.09.2018 19:45

Привет, я только что понял, что функция, которую вызывает ваш avemap, мне не нужна ... Я отредактировал вопрос для вас.

dumbquestionsbydumbpeople 08.09.2018 20:22

Другие вопросы по теме