0

While I am sure there is an answer, and this question is very low-level (but it's always the easy things that trip you up), my main issue is trying to word the question.

Say I have the following arrays:

time=[0,1,2,3,4,5,6,7,8,9,10,11] ;in seconds
data=[0,1,2,3,4,5,6,7,8,9,10,11] 

The 'time' array is in bins of '1s', but instead I would like the array to be in bins of '2s' where the data is then the mean:

time=[0,2,4,6,8,10] ;in seconds
data=[0.5,2.5,4.5,6.5,8.5,10.5] 

Is there (and I am sure there is) an IDL function to implement this in IDL? my actual data array is:

DATA          DOUBLE    = Array[15286473]

so I would rather use an existing, efficient, solution than unnecessarily creating my own.

Cheers, Paul

NB: I can change the time array to what I want by interpolating the data (INTERPOL)

IDL> x=[0,1,2,3,4,5,6,7,8,9,10]
IDL> x_new=interpol(x,(n_elements(x)/2)+1.)
IDL> print, x_new                          
      0.00000      2.00000      4.00000      6.00000      8.00000      10.0000

The issue is just with the data array

2 Answers2

1

I think you need rebin: http://www.exelisvis.com/docs/REBIN.html

congrid provides similar functionality. If rebin does not solve your problem, this should work:

step = 2
select = step * indgen(floor(n_elements/step))
new_time = (smooth(time, step))[select]
new_data = (smooth(data, step))[select]

You might want to set /edge_truncate for smooth, based on your requirements. Also, won't interpol work for you?

VBB
  • 1,305
  • 7
  • 17
  • I find interpol is fine for the time array - as there I just need the time at every 2nd point: IDL> x=[0,1,2,3,4,5,6,7,8,9,10] IDL> x_new=interpol(x,(n_elements(x)/2)+1.) IDL> print, x_new 0.00000 2.00000 4.00000 6.00000 8.00000 10.0000 but couldn't see how it'd work for the data which is going to be the average. I'll check out rebin! I ended up making code similar to yours but it's always nice to know the routine in IDL for the future. – Paul Wright May 01 '15 at 14:08
0

I can think of a few ways to do this, but the easiest would be the following:

nd  = N_ELEMENTS(data)
ind = LINDGEN(nd)
upi = ind[1:(nd - 1L):2]
dni = ind[0:(nd - 1L):2]

where the form of indexing I have used is described here. One can write an array as ind[s0:s1:n] where s0 is the starting element, s1 is the ending element, and n is the stride.

Now that we have the indices for the adjecent elements, then we can define the averages in a vectorized format as:

avg_data = (data[upi] + [dni])/2

You can do something similar to your time stamps or use INTERPOL if you wish.

There are more complicated methods (e.g., the trapezoid rule) to doing this, but the above is a quick and simple solution.

honeste_vivere
  • 308
  • 5
  • 11