SPC常见的四类异常点的检验方式,前端实现的方法,实现的效果如下
只要通过逻辑获取到异常点对应的所在数组的下标,画出这种折线图并不困难,所以只放一下自己实现的逻辑片段
判断第一类异常,超出控制限
// 判断第一类异常,超出控制限
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:有些逻辑的时间复杂度不是最优解法,待优化
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。