1. /**
  2. * Flags anomalous timestamps in an array of timestamps.
  3. *
  4. * @param {Array<number>} timestamps An array of timestamp values (e.g., milliseconds since epoch).
  5. * @param {number} anomalyThreshold The number of standard deviations from the mean to consider a timestamp anomalous.
  6. * @returns {Array<number>} An array of indices of anomalous timestamps. Returns an empty array if input is invalid.
  7. */
  8. function flagTimestampAnomalies(timestamps, anomalyThreshold = 3) {
  9. if (!Array.isArray(timestamps) || timestamps.length === 0) {
  10. return []; // Handle invalid input
  11. }
  12. const n = timestamps.length;
  13. if (typeof anomalyThreshold !== 'number' || anomalyThreshold <= 0) {
  14. anomalyThreshold = 3; //Use default if invalid
  15. }
  16. // Calculate the mean and standard deviation
  17. let sum = 0;
  18. for (let i = 0; i < n; i++) {
  19. if (typeof timestamps[i] !== 'number') {
  20. continue; // Skip non-numeric values
  21. }
  22. sum += timestamps[i];
  23. }
  24. const mean = sum / n;
  25. let sumOfSquares = 0;
  26. for (let i = 0; i < n; i++) {
  27. if (typeof timestamps[i] !== 'number') {
  28. continue; // Skip non-numeric values
  29. }
  30. sumOfSquares += Math.pow(timestamps[i] - mean, 2);
  31. }
  32. const stdDev = Math.sqrt(sumOfSquares / n);
  33. // Identify anomalous timestamps
  34. const anomalousIndices = [];
  35. for (let i = 0; i < n; i++) {
  36. if (typeof timestamps[i] !== 'number') {
  37. continue; // Skip non-numeric values
  38. }
  39. const zScore = Math.abs((timestamps[i] - mean) / stdDev);
  40. if (zScore > anomalyThreshold) {
  41. anomalousIndices.push(i);
  42. }
  43. }
  44. return anomalousIndices;
  45. }

Add your comment