Objective-C:平滑 NSNumber 对象的 NSArray
我有一个 NSArray,其中包含大量 NSNumber 对象(数千个)。我用这些数字来构建一个漂亮的折线图。问题是,该图使用了每个值,这使得该图非常清晰。我拥有的值越多,情况就会变得更糟:
我希望能够将其变成更平滑的图表,可能会丢弃那些使其看起来呈锯齿状的数字。我希望它看起来像这样:
也许已经晚了,但我没有想到一种方法做这个。可能会遍历我的价值观并丢弃其中一些?该图表不需要 100% 准确,它只需要能够很好地表示值即可。
编辑:
这是我使用jrturton的答案想出的方法:
- (NSArray *)smoothedArray:(NSArray *)items {
int average = 0;
int i = 0;
int numberToAverageBy = 10;
NSMutableArray *newItems = [[[NSMutableArray alloc] init] autorelease];
// Loop
for (NSNumber *elevation in items) {
average += [elevation intValue];
i++;
if (i == numberToAverageBy) {
[newItems addObject:[NSNumber numberWithInt:average/numberToAverageBy]];
i = 0;
average = 0;
}//end
}//end for
return [NSArray arrayWithArray:newItems];
}//end
效果非常好!
I have an NSArray which contains a large number of NSNumber objects (thousands). I use these numbers to build a nice line graph. The problem is, the graph uses every value, which makes the graph very sharp. It gets even worse the more values I have:
I want to be able to make this into a smoother graph, possibly throwing out those numbers that make it jagged looking. I want it to look like this:
Maybe it is late, but I am not thinking of a way to do this. Possibly looping through my values and throwing some of them out? The graph doesn't need to be 100% accurate, it just needs to be a decent representation of the values.
EDIT:
Here is the method that I came up with using jrturton's answer:
- (NSArray *)smoothedArray:(NSArray *)items {
int average = 0;
int i = 0;
int numberToAverageBy = 10;
NSMutableArray *newItems = [[[NSMutableArray alloc] init] autorelease];
// Loop
for (NSNumber *elevation in items) {
average += [elevation intValue];
i++;
if (i == numberToAverageBy) {
[newItems addObject:[NSNumber numberWithInt:average/numberToAverageBy]];
i = 0;
average = 0;
}//end
}//end for
return [NSArray arrayWithArray:newItems];
}//end
It worked perfectly!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以取数组中每 10 个(或您选择的任何元素)元素的平均值,并用它来确定要绘制的点。这也会使绘图更快。
You could take the average value of every 10 (or whatever you choose) elements in the array and use that to determine the points to plot. This would make the drawing quicker as well.
查看移动平均线。
移动平均线越短,它越接近曲线,但它会使曲线变得平滑。
例如,请在此处查看 10 天指数移动平均线:
http:// stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
Look at moving averages.
The shorter the moving average, the closer it hugs the curve but it smooths it out.
For example, check out the 10 day exponential moving average here:
http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
我以前从来没有做过这样的事情,所以我确信其他人可以想出更优雅的解决方案,但这是我会尝试的:
在显示图表之前,而不是扔掉一些元素,为什么不将每个元素设置为它周围一些元素的平均值呢?例如,如果您的数组包含 (2, 1, 3, 5, 4, 3, 8),则它将变成 (2, 2, 3, 4, 4, 5, 8)。为了获得这些值,我取了每个元素及其直接邻居的平均值来获取新元素(除了端盖,我将其保留为原样)。调整在每一步中一起平均的元素数量将使您的图表看起来像您想要的那样平滑。
I've never had to do anything like this before, so I'm sure that others can come up with more elegant solutions, but here's what I would try off the top of my head:
Prior to displaying the graph, instead of throwing out some of the elements, why don't you set each element to the average of some of the elements around it? For example, if your array contains (2, 1, 3, 5, 4, 3, 8), that would turn into (2, 2, 3, 4, 4, 5, 8). To get those values, I took the average of each element and its immediate neighbors to get the new element (except for the endcaps, which I left as is). Playing around with the number of elements you're averaging together at each step would make your graph look as smooth as you want it.
http://en.wikipedia.org/wiki/Gaussian_filter
http://en.wikipedia.org/wiki/Gaussian_filter