Sockness_Rogers
Sockness_Rogers

Reputation: 1683

Get mean of all elements at a given index across multiple arrays

I have about 300 arrays that each have 100 arrays of x and y values. I want to get an array of 100 mean for y values of the 300 arrays. What is the best way to do this? I believe I should use some sort of reduce but am a little lost. Here is what I have so far:

let yval = cohort.map((d, i) => {
    let bin = d3.nest()
        .key(function(d) {
            return i;
        })
        .rollup(function(d) {
            return d;
        })
        .entries(d);

    return bin;
});

console.log(yval);

'cohort' is an array of objects. I want to isolate the 'bins' array in each cohort object. Each of these are 117 elements long. For each bins[i], I want to get the mean of [i] from all of the bins. I want to basically turn the array of 300 arrays of 117 into one array of 117 means. Any help would be greatly appreciated!

Upvotes: 3

Views: 215

Answers (3)

Gerardo Furtado
Gerardo Furtado

Reputation: 102198

D3 already has a method named d3.mean, which:

Returns the mean of the given array of numbers

Therefore, if you want to get the mean for each inner array, all you need is this (where data is your original array):

var arrayOfMeans = data.map(d => d3.mean(d));

Here is a basic demo:

var data = [
  [1, 2, 3, 4, 5],
  [10, 20, 30, 40, 50],
  [100, 200, 300, 400, 500]
];

var arrayOfMeans = data.map(d => d3.mean(d));

console.log(arrayOfMeans)
<script src="https://d3js.org/d3.v5.min.js"></script>

However, your data structure is not very clear right now: the description above the snippet ("I have about 300 arrays that each have 100 arrays of x and y values") is different from the description below the snippet ("'cohort' is an array of objects. I want to isolate the 'bins' array in each cohort object. Each of these are 117 elements long.")! It's very confusing...

So, supposing that you have an array of arrays and that in each inner array you have two values, [x, y], this is how you can use d3.mean for the two means, one for the x value and other for the y value:

var arrayOfMeans = [d3.mean(data.map(d => d[0])), d3.mean(data.map(d => d[1]))];

Or, if you don't like literals:

var arrayOfMeans = d3.range(2).map(d => d3.mean(data.map(e => e[d])));

Here is the demo:

var data = [
  [1, 100],
  [2, 200],
  [3, 300]
];

var arrayOfMeans = [d3.mean(data.map(d => d[0])), d3.mean(data.map(d => d[1]))]

console.log(arrayOfMeans)
<script src="https://d3js.org/d3.v5.min.js"></script>

Upvotes: 5

Naga Sai A
Naga Sai A

Reputation: 10975

To achieve expected use below option of ForEach and array reduce method

  1. First creating loop for 300 arrays using array.ForEach method

  2. Inside loop for each array , I am using reduce to find the mean

var sampleArr = [];// sample array for testing 
var meanList = [];// final Mean list array
for (var i=0; i< 301; i++){
  sampleArr[i] =[]
   for (var j=0; j< 2; j++){
   sampleArr[i].push({
     x:i,
     y:i+1
   })
}
}

getMean = arr => {
  arr.forEach(e => {
    let sum = e.reduce(function(a, c) {
      console.log(a, c);
      return a.y + c.y;
    });
    meanList.push(sum / e.length);
  });
};

getMean(sampleArr)

console.log(meanList);

I have created sample array of length 300 and each with 2 arrays for testing

code sample - https://codepen.io/nagasai/pen/eMXNMZ?editors=1010

Upvotes: 0

J. Kamien
J. Kamien

Reputation: 51

There's already an answer to how to calculate the mean of an array in JS:

Finding the average of an array using JS

You could use the function defined in that answer, and map it across the array of arrays. For example:

var result = cohort.map(cohortElement => cohortElement.bin).map(/*function declared in other StackOverflow answer*/)

Upvotes: 0

Related Questions