How to bin polar coordinates
7 次查看(过去 30 天)
显示 更早的评论
I have a list of theta and a corresponding value between 0 and 1. I would like to bin all the corresponding values into bins of 1 degree.
edges = -180:1:180
X % random list of angles between -180 and 180
Y % random list of corresponding values between 0 and 1
[bins] discretize(X,edges);
yBinned = arrayfun(@(i)Y(bins==i),unique(bins),'UniformOutput', false);
This gives me an array of only 180 entries in Ybinned, which should be 360?
Any fix or alternative method for binning polar coordinates in Matlab?
Thanks
0 个评论
回答(1 个)
Dave B
2021-11-24
编辑:Dave B
2021-11-24
The way you've written the code, the number of outputs in yBinned depends on how many of the bins of X were populated.
edges = -180:1:180;
X = rand(100,1)*360-180;
Y = rand(100,1);
bins = discretize(X,edges);
yBinned = arrayfun(@(i)Y(bins==i),unique(bins),'UniformOutput', false);
size(yBinned)
numel(unique(bins))
If you want yBinned to correspond to the bin number, you'll need empty placeholders for cases where the bin is empty.
Method 1: somewhat wasteful, but keeps the one-liner aspect. Instead of applying the function to the populated bins (unique(bins)) apply it to the potential bins (numel(edges)-1)
yBinned = arrayfun(@(i)Y(bins==i),1:numel(edges)-1,'UniformOutput', false);
size(yBinned)
Method 2: Uses the same approach as you took to calculate the filled bins, but then distributes them into a vector. I think this is harder to read...but I suppose more efficient (I'd probably pull the unique(bins) part out if performance was really a concern).
yBinnedFull = arrayfun(@(i)Y(bins==i),unique(bins),'UniformOutput', false);
yBinned = cell(numel(edges)-1,1); % initialize in case trailing bins weren't populated
yBinned(unique(bins)) = yBinnedFull;
Note that these produce very slightly different results: method 1's empties are a 0x1 double, and method 2's empties are a 0x0 double.
2 个评论
Dave B
2021-11-24
Yes - more specifically it finds the y values for each bin (and you defined bins as one bin per degree).
There's not an obvious difference between 0x0 and 0x1, they're both empty (neither one gets a 0 in the cell) and for most practical purposes they probably are the same.
But, if you're curious...in MATLAB a matrix can be empty by having no height (and any amount of width) or having no width (and any amount of height) or neither height no width (or really any dimension can be zero-sized). The difference rarely matters, and I probably just added confusion by mentioning it...but when I answer with two different methods I normally check that they produce the same result with isequal...and here they don't. Here's some more detail:
edges = -180:1:180;
rng(0); %for reproducibility
X = rand(500,1)*360-180;
Y = rand(500,1);
bins = discretize(X,edges);
a = arrayfun(@(i)Y(bins==i),1:numel(edges)-1,'UniformOutput', false);
yBinnedFull = arrayfun(@(i)Y(bins==i),unique(bins),'UniformOutput', false);
b = cell(1,numel(edges)-1); % initialize in case trailing bins weren't populated
b(unique(bins)) = yBinnedFull;
a(1:10)
b(1:10)
% demo that these are different (even though they're both empty)
a{4}
b{4}
isempty(a{4})
isempty(b{4})
% just a demo that they're the same if we look at an entry with more than one value
a{6}
b{6}
% complete comparison
ind_a = ~cellfun(@isempty,a);
ind_b = ~cellfun(@isempty,b);
isequal(ind_a,ind_b) % same set if values is empty
isequal(a(ind_a),b(ind_b)) % the non-empty values are the same
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrices and Arrays 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!