Skip to main content
5 of 5
added 54 characters in body
Roman
  • 49.8k
  • 2
  • 57
  • 131

I'll assume here that the bins are equally spaced.

Starting like @HenrikSchumacher suggests:

data = Join[RandomReal[{0, 4}, {5, 6, 780, 90, 1}], RandomReal[{0, 1}, {5, 6, 780, 90, 1}], 5];
data1 = Flatten[data, 3];

If your data need to be weighted depending on their four indices, you could instead first do something like

weighteddata = MapIndexed[{#1[[1]], f[#1[[2]],#2]}&, data, {4}];

with f some function you define that does the weighting. Then use data1 = Flatten[weighteddata, 3] instead.

For each data point, round the $x$-coordinate down to the nearest thousandth (you may use Round or Ceiling instead of Floor to define the bins, depending on what exactly you need):

data2 = {Floor[#[[1]], 0.001], #[[2]]} & /@ data1;

Gather together all data points with the same $x$-coordinate (rounded down to the nearest thousandth):

A = GatherBy[data2, First];

From these gathered lists, calculate for each bin (i) the $x$-value of the lower bin edge (or the center of the bin, or whatever) and (ii) the sum of the $y$-values (or the mean, or length, or whatever):

B = (#[[1, 1]] -> Total[#[[All, 2]]]) & /@ A;

The results in B are in random order. Make an ordered list of all bins and their sum:

bins = Range[0, 4, 0.001];
Transpose[{bins, Lookup[B, bins, 0]}]

{{0, ...}, {0.001, ...}, {0.002, ...}, ..., {4, ...}}

(The dots stand for the sum values in each bin.)

If you prefer having the bin centers as first coordinate instead of the bin lower limits, then you could do

bins = Range[0, 3.999, 0.001];
Transpose[{bins+0.0005, Lookup[B, bins, 0]}]

{{0.0005, ...}, {0.0015, ...}, {0.0025, ...}, ..., {3.9995, ...}}

I agree with @HenrikSchumacher that BinLists is nicer than my use of GatherBy here.

Roman
  • 49.8k
  • 2
  • 57
  • 131