Objective c Obj-C:计算NSNumber对象的NSArray的标准偏差?
如果我有一个Objective c Obj-C:计算NSNumber对象的NSArray的标准偏差?,objective-c,cocoa,Objective C,Cocoa,如果我有一个NSArray的NSNumber对象,如何计算数组中数字的标准偏差?这里有一个可以使用的算法。我不知道有任何内置的Objective C统计库,所以我只需要自己实现算法。这个链接是用Java实现的,但是它应该很容易转换。有一些很好的代码。要查看NSArray(而不是示例中的C数组),只需在实现SDAccum时使用以下代码: - (double)computeStandardDeviationWithArray:(NSArray *)numberArray { double s
NSArray
的NSNumber
对象,如何计算数组中数字的标准偏差?这里有一个可以使用的算法。我不知道有任何内置的Objective C统计库,所以我只需要自己实现算法。这个链接是用Java实现的,但是它应该很容易转换。有一些很好的代码。要查看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;
}
假设将所有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])];
}
这是我不久前使用的另一个版本
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);
您可以使用
NSExpression
内置函数
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...
有关更多信息,请查看官方网站和本网站。这里是NSArray的一个类别,以便于执行类似的任务,使用NSExpression,类似于Tiago的方法。可以将其作为字符串传递(函数中添加了冒号) 像这样使用:
NSNumber *result = [myArray calculateStat:@"stddev"];
+该死的,你比我快。如果您需要比双精度更高的精度,您可以始终切换到
NSDecimal
。速度会慢一些,但这就是精度的代价。:)如果是样本偏差,请不要忘记执行sumOfSquaredDifferences/([array count]-1):PWhy迭代两次?sum(1,n)(Xi-M)^2==sum(1,n)Xi^2-(sum(1,n)Xi)^2/n所以迭代一次,累加平方和和和和。(这是一个计算器是如何做到的。)好吧,这可能是一个小数组的小优化,但对于一个常用的统计方法。。。如果你真的关心精度,请咨询Knuth。没有理由进行双重迭代;你的肯定会有进步。对于精度,我假设在实际应用程序中,您会更好地了解将什么类型的数字打包到NSNumbers中,以及需要什么类型的精度代码>非常聪明的答案!我认为这是最好的答案。当0是数组中的一个元素时,DDEV:存在准确性问题。为了正确起见,STDEV计算“总体标准偏差”,而不是样本标准偏差这是一个很好的答案!只是,我尝试了N表达式和直接计算(平均值,然后是与平均值之差的平方和,然后是方差,然后是STDEV)--都是双倍的,但由于某种原因,结果中存在非标准偏差……在我的例子中,(仅6个数字)1.82(计算)和1.94(N表达式)之间的差异。相信谁?这是一个很好的诡计,可以将NSExpression内部函数“输出”到数组接口。实际上,您可以更进一步,@dynamic ally(在运行时)以一种通用的方式将这些方法添加到NSArray中……因此“stddev”将显示为[myArray stddev];
NSNumber *result = [myArray calculateStat:@"stddev"];