关于SPC控制图常见的异常点检验的判定逻辑

SPC常见的四类异常点的检验方式,前端实现的方法,实现的效果如下

关于SPC控制图常见的异常点检验的判定逻辑_第1张图片

关于SPC控制图常见的异常点检验的判定逻辑_第2张图片


只要通过逻辑获取到异常点对应的所在数组的下标,画出这种折线图并不困难,所以只放一下自己实现的逻辑片段

判断第一类异常,超出控制限

//  判断第一类异常,超出控制限
const adNormal1 = () => {
  // mock数据,待判断的数组
  const yData: number[] = [];
  //mock数据,上下控制限
  const mock_uplimit: number = 100;
  const mock_lowLimit: number = 0;

  //  判断第一类异常,超出控制限
  for (let i: number = 0; i < yData.length; i++) {
    if (yData[i] > mock_uplimit || yData[i] < mock_lowLimit) {
      console.log(`该点异常,点的Index:${i},点的数据:${yData[i]}`);
    }
  }
};

判断第二类异常,连续n点在一侧

const adNormal2 = () => {
  // mock数据,待判断的数组
  const yData: number[] = [];
  //mock数据,连续n点在一侧的控制限
  const mock_middle: number = 66;
  // mock数据,连续n点在一侧的n
  const mock_n: number = 5;

  //  判断第二类异常,连续n点在一侧
  const tempAdnormalIndex: number[] = [];

  for (let i: number = 0; i < yData.length - mock_n + 1; i++) {
    let tempGroup: number[] = [];
    for (let j: number = i; j < i + mock_n; j++) {
      if (yData[j] > mock_middle) tempGroup.push(1);
      if (yData[j] === mock_middle) tempGroup.push(0);
      if (yData[j] < mock_middle) tempGroup.push(-1);
    }
    if ([...new Set(tempGroup)].length === 1 && tempGroup.indexOf(0) === -1) {
      for (let j: number = i; j < i + mock_n; j++) {
        tempAdnormalIndex.push(j);
      }
    }
  }

  const finalAdnormalIndex: number[] = [...new Set(tempAdnormalIndex)];
  //得到一个连续的点的数组下标的去重后的数组
  finalAdnormalIndex.forEach((item: number) => console.log(`该点异常,点的Index:${item},点的数据:${yData[item]}`));
};

判断第三类异常,连续n点上升或下降

const adNormal3 = () => {
  // mock数据,待判断的数组
  const yData: number[] = [];
  // mock数据,连续n点上升或下降的n
  const mock_n: number = 3;

  //  判断第三类异常,连续n点上升或下降
  const tempAdnormalIndex: number[] = [];

  for (let i: number = 0; i < yData.length - mock_n + 1; i++) {
    let tempGroup: number[] = [];
    // 先处理该组的第一个值,首先push 0 ,待填充完毕后,设置为第二位的数据的相同的趋势
    tempGroup.push(0);
    for (let j: number = i; j < i + mock_n - 1; j++) {
      if (yData[j + 1] > yData[j]) tempGroup.push(1);
      if (yData[j + 1] === yData[j]) tempGroup.push(0);
      if (yData[j + 1] < yData[j]) tempGroup.push(-1);
    }
    // 待填充完毕后,设置为第二位的数据的相同的趋势
    tempGroup[0] = tempGroup[1];
    if ([...new Set(tempGroup)].length === 1 && tempGroup.indexOf(0) === -1) {
      for (let j: number = i; j < i + mock_n; j++) {
        tempAdnormalIndex.push(j);
      }
    }
  }

  const finalAdnormalIndex: number[] = [...new Set(tempAdnormalIndex)];
  //得到一个连续的点的数组下标的去重后的数组
  finalAdnormalIndex.forEach((item: number) => console.log(`该点异常,点的Index:${item},点的数据:${yData[item]}`));
};

判断第四类异常,.连续n点交替上升或下降

const adNormal4 = () => {
  // mock数据,待判断的数组
  const yData: number[] = [];
  // mock数据,连续n点交替上升或下降的n
  const mock_n: number = 6;

  //  判断第四类异常,.连续n点交替上升或下降

  const tempAdnormalIndex: number[] = [];

  for (let i: number = 0; i < yData.length - mock_n + 1; i++) {
    let tempGroup: number[] = [];
    // 先处理该组的第一个值,首先push 0 ,待填充完毕后,设置为第二位的数据的相反的趋势
    tempGroup.push(0);
    for (let j: number = i; j < i + mock_n - 1; j++) {
      if (yData[j + 1] > yData[j]) tempGroup.push(1);
      if (yData[j + 1] === yData[j]) tempGroup.push(0);
      if (yData[j + 1] < yData[j]) tempGroup.push(-1);
    }

    // 待填充完毕后,设置为第二位的数据的相反的趋势
    tempGroup[0] = tempGroup[1] === 0 ? 0 : -tempGroup[1];

    //  判断tempGroup数组是否为1,-1的连续交叉,若为此情况,说明是交替上升或下降
    let isAbnormal4: boolean = true;

    // 若有相同的情况,则说明不满足
    if (tempGroup.indexOf(0) > -1) {
      isAbnormal4 = false;
    }
    // 判断tempGroup数组是否为1,-1的连续交叉
    else {
      for (let k: number = 0; k < tempGroup.length - 1; k++) {
        if (tempGroup[k] + tempGroup[k + 1] !== 0) isAbnormal4 = false;
      }
    }

    // 若该组满足交替上升,将该组数据的下标填入tempAdnormal4Y1Index
    if (isAbnormal4) {
      for (let j: number = i; j < i + mock_n; j++) {
        tempAdnormalIndex.push(j);
      }
    }
  }

  const finalAdnormalIndex: number[] = [...new Set(tempAdnormalIndex)];
  //得到一个连续的点的数组下标的去重后的数组
  finalAdnormalIndex.forEach((item: number) => console.log(`该点异常,点的Index:${item},点的数据:${yData[item]}`));
};

PS:有些逻辑的时间复杂度不是最优解法,待优化

你可能感兴趣的:(关于SPC控制图常见的异常点检验的判定逻辑)