Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a list of (x,y) values in Mathematica for various discrete x values, as in

intensities={{26, 10}, {27, 289}, {28, 90}, {29, 1079}, {30, 30}, {33, 10}, {39, 
  179}, {40, 40}, {41, 2269}}

I would now like to insert into this list explicit zeros for each discrete value of x that has a nonexisting y value, as in

intensities2={{0,0},{1,0},{2,0},....,{26,10},{27,289},{28,90},...,{41,2269}}

Out of these I would then like to extract just the y values to be able to do a discrete Forier transform on them. Any thoughts how I could do this most efficiently?

cheers & many thanks for any advice! Tom

share|improve this question
    
Something like this can be used to get zeroes with specific values altered. ilist = ConstantArray[0, Max[intensities[[All, 1]]]]; Map[(ilist[[#[[1]] + 1]] = #[[2]]) &, intensities]; –  Daniel Lichtblau Nov 6 '13 at 17:35
    
@PlatoManiac: yes, sorry - I edited it now... –  Tom Wenseleers Nov 6 '13 at 17:41
    
@DanielLichtblau, since Tom wants the x values to start at 0, shouldn't you use ilist=ConstantArray[0,1+intensities[[-1,1]]];Map[(ilist[[#[[1]]+1]]=#[[2]])&,in‌​tensities]; ? This then gives ilist as the answer Tom wants I think. This is a simpler solution than the one I posted below, but after all these years I still find the myriad uses of Map hard to understand. –  Jason B Nov 6 '13 at 17:45
    
@JasonB Yes one can alter that code to get a list of ordered pairs. I had indeed skipped that and gone directly to "extract[ing] just the y values". –  Daniel Lichtblau Nov 6 '13 at 18:16
add comment

3 Answers

up vote 4 down vote accepted

What about this!

Normal@SparseArray[{#1} -> #2 & @@@ intensities]

Be careful that it works if the list intensities2 starts with {1,x} not {0,x} and input list intensities has no entries like {0,x}.

If you persist on starting intensities2 with {0,x} and given that input list intensities will have increasing x values then try the following

With[{zero = First@#},
    If[zero[[1]] === 0,
        ({zero[[2]]}~Join~SparseArray[{#1} -> #2 & @@@ Rest[#]]),
        {0}~Join~SparseArray[{#1} -> #2 & @@@ #]
  ]
 ] &@intensities; // AbsoluteTiming

In order to check efficiency you will need to create bigger example data. You can do so using the following.

samplesize = 10^6; 
intensities =Sort@Transpose@(RandomSample[#,samplesize] &/@
(Range[0, #] & /@ {10 samplesize,10 samplesize}));
share|improve this answer
    
Many thanks for this - brilliant! I like the other answers too, but this one is really compact! I always have trouble coming up with such compact solutions, typically resorting to old school Do loops :-) –  Tom Wenseleers Nov 6 '13 at 17:49
    
Slick (and an upvote). –  Daniel Lichtblau Nov 6 '13 at 18:17
add comment

belisarius's answer is more elegant I'm sure, but I like a straightforward use of Table and Do whenever possible.

intensities={{26,10},{27,289},{28,90},{29,1079},{30,30},{33,10},{39,179},{40,40},{41,2269}};
intensities2=Table[{n,0},{n,0,intensities[[-1,1]]}];
Do[
  intensities2[[intensities[[n,1]]+1]]=intensities[[n]];
  ,{n,Length[intensities]}]

Then when you want to extract just the second column of the data, just the y values, you use

intensities2[[All,2]]
share|improve this answer
add comment
(Join[{#, 0} & /@ Complement[Range@Max@#[[All, 1]], #[[All, 1]]], #] &@ints)[[All,2]]
share|improve this answer
    
in your post, is ints equal to OP's intensities? Also, it seemed to work better before the edit, although it didn't give the {0,0} element. When I enter what you have now, I only get the second column. –  Jason B Nov 6 '13 at 17:36
    
@JasonB "Out of these I would then like to extract just the y values" ... –  belisarius Nov 6 '13 at 17:49
    
yeah I saw that after I made this comment. I'm still confused about whether the OP needed the x values to start at 0 or 1. In his question it seemed that he wanted it to start at 0, so the resulting answer should be a one-dimensional list with 42 elements. But the answer he accepted doesn't fit that criteria. –  Jason B Nov 6 '13 at 17:53
    
@JasonB I edited my answer to fit the case you mentioned. –  PlatoManiac Nov 6 '13 at 18:45
    
@JasonB Me neither, but it's his question :) –  belisarius Nov 6 '13 at 19:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.