Re-bin My Data is Discrete Energy Values

Hi I am trying to rebin my data is discrete values.
Energy Amount
11.8652 3.5891
12.5513 6.6741
11.8652 3.5891
8.8125 1.1711
8.8125 2.3422
8.8125 1.1711
5.7598 0.3324
5.0737 0.9444
5.7598 0.3324
12.5513 6.6741
14.1000 19.0596
12.5513 6.6741
8.8125 2.3422
0.0000 0.0000
8.8125 2.3422
5.0737 0.9444
3.5250 7.2712
5.0737 0.9444
11.8652 3.5891
12.5513 6.6741
11.8652 3.5891
8.8125 1.1711
8.8125 2.3422
8.8125 1.1711
5.7598 0.3324
5.0737 0.9444
5.7598 0.3324
I am very thankful that Walter Roberson helped me with < * http://www.mathworks.com/matlabcentral/answers/22879-binning-for-a-histogram a very useful technique> as follows.
[uvals, a, uidx] = unique(YourData(:,1));
Sum = accumarray(uidx, YourData(:,2));
plot(uvals, Sum)
However, I am unable to bin the data in discrete bins. For example, I would like to re-bin my data from 1-2 Energy and then 2-3 Energy so and so. Bascially, I would like a histogram that shows the Energy values in the x-axis. I hope this is clear.

 Accepted Answer

Sum = histc(YourData, BinBoundaries);

18 Comments

Sorry, your question was not clear. Try
[unneeded, binidx] = histc(YourData(:,1), BinBoundaries);
Sum = accumarray(binidx(:), YourData(:,2));
plot(BinBoundaries, Sum);
However, if you have any values that are exactly equal to the largest bin boundary you specified, then Sum will have one value more than BinBoundaries, so you will need to account for that.
Hi Walter,
Your first method work really well. For example,
Energy Amount
1.2 3.2
1.2 4.5
1.5 1.2
2.1 3.2
2.7 2.5
4.5 1.2
4.5 3.5
6.5 3.0
7.3 2.1
9.1 1.2
9.6 3.5
And the code you gave me originally works great such as,
Energy Amount
1.2 7.7
1.5 1.2
2.1 3.2
2.7 2.5
4.5 4.7
6.5 3.0
7.3 2.1
9.1 1.2
9.6 3.5
So the energy values of 1.2 and 4.5 are the same and they are added. This works great for my code. But what I am struggling with is now binning the data for example,
Energy Amount
1-2 8.9
2.1-3 5.7
3.1-4 0
4.1-5 4.7
5.1-6 0
6.1-7 3.0
7.1-8 2.1
8.1-9 0
9.1-10 4.7
Then plot(Energy,Amount). I hope this is much clearer. And thank you very much. You have been very helpful.
What do those "Energy" values indicate? They appear to be bin boundaries and in the sample data you show, they are unique, and thus appear to already be binned. What would you like done?
Yes..the sample data is unique. I am just trying to put the two values for Energy and Amount 1.2 and 1.5 into one bin with their values added together. So one bin of from Energy 1-2 will have the 7.7 + 1.2. It seems very simple but I cannot get it to work.
Read the first column as text and throw away the '-' to the end of the column, and convert the resulting strings to a vector. histc() that vector against the same BinBoundaries as you used before,
[unneeded, binidx] = histc(TheEnergies, BinBoundaries);
Read the second column, Amount, as numbers (this can be done at the same time you read the first column).
Then,
NewSum = accumarray(binidx(:), TheAmounts(:), size(Sum));
Sum = Sum + NewSum;
I used accumarray just in case the bins were not exactly the same, such as if the new file did not extend as far as the existing data. Also, I noticed that the new file has 1-2 as the first bin whereas 1.1-2 is what would be expected based upon the other entries; this indicates the potential for a bin numbering difference from 1 to 1.1
My real numbers are very random. So it really should be 1-1.99999 for one bin and then 2-2.9999 for then next. I guess I was not clear. Also, I was hoping to plot this as a histgram according to the energy bin. So maybe I should not be using plot. What do you suggest?
I said to read them as text because MATLAB is not able to store a number that has a - sign in the middle such as '2.1-3' . Whether you intended it to or not, there is no space in that between the '1' and the '-' so it has to have been stored as text. If you already have it as a text string then just proceed to throwing away the '-' onwards.
Histogram:
hist(BinBoundaries, Sum);
I said to read them as text because MATLAB is not able to store a number that has a - sign in the middle such as '2.1-3' . Whether you intended it to or not, there is no space in that between the '1' and the '-' so it has to have been stored as text. If you already have it as a text string then just proceed to throwing away the '-' onwards.
Histogram:
bar(BinBoundaries, Sum);
Alright...I am still a little confused. I think I confused you more. Anyway, I am very close to getting this. I first start with,
Energy Amount
1.2 3.2
1.2 4.5
1.5 1.2
2.1 3.2
2.7 2.5
4.5 1.2
4.5 3.5
6.5 3.0
7.3 2.1
9.1 1.2
9.6 3.5
I then use the first set of code you provided to do the following.
Energy Amount
1.2 7.7
1.5 1.2
2.1 3.2
2.7 2.5
4.5 4.7
6.5 3.0
7.3 2.1
9.1 1.2
9.6 3.5
This is now the discrete energy value and the amounts added up. This is what I was looking for. Now I want to re-bin and I do the following.
[unneeded, binidx] = histc(Energy, 1:1:14) which gives,
[unneeded, binidx] = histc(Energy, 1:1:14)
unneeded =
2 2 0 1 0 1 1 0 2 0 0 0 0 0
binidx =
1 1 2 2 4 6 7 9 9
And this is correct. I then do the following.
Sum = accumarray(binidx(:), Amount)
Which gives,
Sum =
8.9000
5.7000
0
4.7000
0
3.0000
2.1000
0
4.7000
Which is what I was looking for. I then do bar(Sum) and this is correct. But, what does not work and I have no idea why is when I change from (1:.1:14). I do the same steps and my bar plot is out to 89..not 8.9. I am confused by that.
Wait..I had that wrong. My bins are correct..but the x-scale is off. For exampe, where I expect Energy (x-value) at 1.2 = 7.7 I get x = 3 and y = 7.7. I hope I am not confusing you...:)
Basically...when I do bar(BinBoundaries, Sum) it complains that the lengths are not the same. And they are not. So this works except the x-scale is off.
You need to pass your bin boundaries as the first parameter to bar()
For example,
bar(1:.1:14, Sum)
I do...but when I do
Sum =
8.9000
5.7000
0
4.7000
0
3.0000
2.1000
0
4.7000
I only get 9 values. 10,11,12,13,14 have been excluded. Therefore, BinBoundaries is (1:1:14) is 14 values...so what can i do keep the zero's? And I really appreaciate your help..
Replace
Sum = accumarray(binidx(:), Amount)
with
Sum = accumarray(binidx(:), Amount, length(unneeded))
Sum = accumarray(binidx(:), Amount, length(unneeded))
??? Error using ==> accumarray
Third input SZ must be a full row vector with one element for each column of SUBS.
I keep getting this error. I cannot find accumarry in my help. But it works. That is odd.
Okay..I found it in my help. but I cannot get the zero's I need...so frustating..
Sum = accumarray(binidx(:), Amount, [length(unneeded),1] )
Thanks...I have a good clean working script. Very helpful..
Chad

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!