Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Obj-C:计算NSNumber对象的NSArray的标准偏差?_Objective C_Cocoa - Fatal编程技术网

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"];