【数据处理】中位数绝对偏差,排除异常值,少数服从多数

在统计学中,有一种称为 中位数绝对偏差(Median Absolute Deviation,MAD) 的方法,可以用来识别异常值并将其排除在外。MAD是一种基于中位数的离散度量,它可以帮助识别数据集中的异常值。

具体步骤如下:

  1. 计算数据集的中位数。
  2. 计算每个数据点与中位数的绝对偏差。
  3. 计算这些绝对偏差的中位数,即MAD。

通过设置阈值,例如MAD的倍数,来判断哪些数据点被认为是异常值。

#include <stdio.h>
#include <stdlib.h>

// 计算中位数
float median(int arr[], int n) {
    float median_val;
    if (n % 2 == 0) {
        median_val = (arr[n/2 - 1] + arr[n/2]) / 2.0;
    } else {
        median_val = arr[n/2];
    }
    return median_val;
}

// 计算绝对值
int abs_val(int x) {
    return (x < 0) ? -x : x;
}

// 计算中位数绝对偏差(MAD)
float mad(int arr[], int n) {
    float median_val = median(arr, n);
    int deviations[n];
    for (int i = 0; i < n; i++) {
        deviations[i] = abs_val(arr[i] - median_val);
    }
    return median(deviations, n);
}

// 交换两个元素的值
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 快速排序函数(非递归)
void quickSort(int arr[], int low, int high) {
    if (low >= high) return; // 添加基本情况处理
    int stack[high - low + 1]; // 创建一个栈
    int top = -1; // 栈顶指针

    stack[++top] = low;
    stack[++top] = high;

    while (top >= 0) {
        high = stack[top--];
        low = stack[top--];

        int pivot = arr[high];
        int i = low - 1;

        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(&arr[i], &arr[j]);
            }
        }

        swap(&arr[i + 1], &arr[high]);
        int pi = i + 1;

        if (pi - 1 > low) {
            stack[++top] = low;
            stack[++top] = pi - 1;
        }

        if (pi + 1 < high) {
            stack[++top] = pi + 1;
            stack[++top] = high;
        }
    }
}

int main() {
    // int data[] = {50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 40};
    int data[] = {50, 50, 50, 50, 50, 50, 30, 20, 10, 5, 5, 5};
    int n = sizeof(data) / sizeof(data[0]);
    quickSort(data, 0, n - 1);

    float threshold = 1.5; // 设置MAD的倍数阈值
    float median_abs_dev = mad(data, n);

    // 排除异常值
    for (int i = 0; i < n; i++) {
        if (abs_val(data[i] - median(data, n)) > threshold * median_abs_dev) {
            data[i] = median(data, n);
        }
    }

    // 计算剩余数值的平均值
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += data[i];
    }
    float average = (float)sum / n;

    printf("剔除异常值后的平均值: %.2f\n", average);

    return 0;
}

剔除异常值后的平均值: 50.00
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值