如果我有NSArray
个NSNumber
个对象,如何计算数组中数字的标准差?
答案 0 :(得分:24)
假设将所有NSNumber作为双倍长度浮点数进行处理是安全的(如果你在该范围的极端有一些64位整数,那么你将失去一些精度)并且我已经正确地记住了公式实施可能是:
- (NSNumber *)meanOf:(NSArray *)array
{
double runningTotal = 0.0;
for(NSNumber *number in array)
{
runningTotal += [number doubleValue];
}
return [NSNumber numberWithDouble:(runningTotal / [array count])];
}
- (NSNumber *)standardDeviationOf:(NSArray *)array
{
if(![array count]) return nil;
double mean = [[self meanOf:array] doubleValue];
double sumOfSquaredDifferences = 0.0;
for(NSNumber *number in array)
{
double valueOfNumber = [number doubleValue];
double difference = valueOfNumber - mean;
sumOfSquaredDifferences += difference * difference;
}
return [NSNumber numberWithDouble:sqrt(sumOfSquaredDifferences / [array count])];
}
答案 1 :(得分:24)
您可以使用NSExpression
内置功能。</ p>
NSArray *numbers = @[@1, @2, @3, @4, @5, @6, @7, @8];
NSExpression *expression = [NSExpression expressionForFunction:@"stddev:" arguments:@[[NSExpression expressionForConstantValue:numbers]]];
NSNumber *value = [expression expressionValueWithObject:nil context:nil];
NSLog(@"%@,", value); // => 2.29128...
有关详细信息,请查看官方documentation和此NSHipster article。
答案 2 :(得分:1)
这里有一个NSArray的类别,用于促进类似的任务,使用NSExpression,类似于Tiago的方法。您可以将其作为字符串any NSExpression that you wish to calculate传递(在函数中添加冒号)。
@interface NSArray (Stats)
- (NSNumber *)calculateStat:(NSString *)stat;
@end
@implementation NSArray (Stats)
- (NSNumber *)calculateStat:(NSString *)stat
{
NSArray *args = @[[NSExpression expressionForConstantValue:self]];
NSString *statFormatted = [stat stringByAppendingString:@":"];
NSExpression *expression = [NSExpression expressionForFunction:statFormatted arguments:args];
return [expression expressionValueWithObject:nil context:nil];
}
@end
像这样使用:
NSNumber *result = [myArray calculateStat:@"stddev"];
答案 3 :(得分:0)
这是您可以使用的算法的link。我不知道任何内置的Objective C统计库,所以我只想自己实现该算法。该链接在Java中完成,但它应该很容易转换。
答案 4 :(得分:0)
Rosetta Code上有一些很好的代码。要通过NSArray(而不是像他们的示例中那样使用C数组),只需使用此代码及其SDAccum的实现:
- (double)computeStandardDeviationWithArray:(NSArray *)numberArray
{
double sd;
SDAccum *sdacc = [[SDAccum alloc] init];
for(NSNumber *aNumber in numberArray)
{
sd = [sdacc value: [aNumber doubleValue]];
}
[sdacc release];
return sd;
}
答案 5 :(得分:0)
这是我前段时间使用的另一个版本。
NSArray *numbers = [NSArray arrayWithObjects:[NSNumber numberWithInt:...],
[NSNumber numberWithInt:...],
[NSNumber numberWithInt:...], nil];
// Compute array average
int total = 0;
int count = [numbers count];
for (NSNumber *item in numbers) {
total += [item intValue];
}
double average = 1.0 * total / count;
// Sum difference squares
double diff, diffTotal = 0;
for (NSNumber *item in numbers) {
diff = [item doubleValue] - average;
diffTotal += diff * diff;
}
// Set variance (average from total differences)
double variance = diffTotal / count; // -1 if sample std deviation
// Standard Deviation, the square root of variance
double stdDeviation = sqrt(variance);