///|
pub enum MissingValuePolicy {
Reject
Zero
Mean
CarryForward
} derive(ToJson, FromJson, Debug, Eq)
///|
pub struct DataQualityReport {
mut rows : Int
mut accepted : Int
mut rejected : Int
mut missing_values : Int
mut dimension_errors : Int
mut out_of_range : Int
}
///|
pub fn DataQualityReport::new() -> DataQualityReport {
{
rows: 0,
accepted: 0,
rejected: 0,
missing_values: 0,
dimension_errors: 0,
out_of_range: 0,
}
}
///|
pub fn DataQualityReport::observe(
self : DataQualityReport,
accepted : Bool,
missing : Int,
dimension_error : Bool,
range_error : Bool,
) -> Unit {
self.rows += 1
self.missing_values += missing
if dimension_error {
self.dimension_errors += 1
}
if range_error {
self.out_of_range += 1
}
if accepted {
self.accepted += 1
} else {
self.rejected += 1
}
}
///|
pub fn DataQualityReport::rows(self : DataQualityReport) -> Int {
self.rows
}
///|
pub fn DataQualityReport::accepted(self : DataQualityReport) -> Int {
self.accepted
}
///|
pub fn DataQualityReport::rejected(self : DataQualityReport) -> Int {
self.rejected
}
///|
pub fn DataQualityReport::missing_values(self : DataQualityReport) -> Int {
self.missing_values
}
///|
pub fn DataQualityReport::dimension_errors(self : DataQualityReport) -> Int {
self.dimension_errors
}
///|
pub fn DataQualityReport::out_of_range(self : DataQualityReport) -> Int {
self.out_of_range
}
///|
pub fn DataQualityReport::acceptance_rate(self : DataQualityReport) -> Double {
if self.rows == 0 {
0.0
} else {
self.accepted.to_double() / self.rows.to_double()
}
}
///|
pub fn DataQualityReport::reset(self : DataQualityReport) -> Unit {
self.rows = 0
self.accepted = 0
self.rejected = 0
self.missing_values = 0
self.dimension_errors = 0
self.out_of_range = 0
}
///|
pub struct FeatureRangeMonitor {
lower : Array[Double]
upper : Array[Double]
minimum : Array[Double]
maximum : Array[Double]
violations : Array[Int]
}
///|
pub fn FeatureRangeMonitor::new(
lower : Array[Double],
upper : Array[Double],
) -> FeatureRangeMonitor {
let size = if lower.length() < upper.length() {
lower.length()
} else {
upper.length()
}
{
lower: Array::makei(size, i => lower[i]),
upper: Array::makei(size, i => upper[i]),
minimum: Array::make(size, 0.0),
maximum: Array::make(size, 0.0),
violations: Array::make(size, 0),
}
}
///|
pub fn FeatureRangeMonitor::observe(
self : FeatureRangeMonitor,
features : Array[Double],
) -> Bool {
let mut valid = true
let limit = if features.length() < self.lower.length() {
features.length()
} else {
self.lower.length()
}
for i in 0.. self.upper[i] {
self.violations[i] += 1
valid = false
}
if self.violations[i] == 0 || value < self.minimum[i] {
self.minimum[i] = value
}
if self.violations[i] == 0 || value > self.maximum[i] {
self.maximum[i] = value
}
}
if features.length() != self.lower.length() {
valid = false
}
valid
}
///|
pub fn FeatureRangeMonitor::violations(
self : FeatureRangeMonitor,
) -> Array[Int] {
self.violations.map(value => value)
}
///|
pub fn FeatureRangeMonitor::minimum(
self : FeatureRangeMonitor,
) -> Array[Double] {
copy_vector(self.minimum)
}
///|
pub fn FeatureRangeMonitor::maximum(
self : FeatureRangeMonitor,
) -> Array[Double] {
copy_vector(self.maximum)
}
///|
pub fn FeatureRangeMonitor::reset(self : FeatureRangeMonitor) -> Unit {
self.minimum.fill(0.0)
self.maximum.fill(0.0)
self.violations.fill(0)
}
///|
pub struct DuplicateSignatureTracker {
signatures : Map[String, Int]
mut rows : Int
mut duplicates : Int
}
///|
pub fn DuplicateSignatureTracker::new() -> DuplicateSignatureTracker {
{ signatures: {}, rows: 0, duplicates: 0 }
}
///|
pub fn DuplicateSignatureTracker::observe(
self : DuplicateSignatureTracker,
features : Array[Double],
) -> Bool {
let signature = features.map(value => "\{value}").join(",")
self.rows += 1
if self.signatures.contains(signature) {
self.duplicates += 1
self.signatures[signature] += 1
true
} else {
self.signatures[signature] = 1
false
}
}
///|
pub fn DuplicateSignatureTracker::rows(self : DuplicateSignatureTracker) -> Int {
self.rows
}
///|
pub fn DuplicateSignatureTracker::duplicates(
self : DuplicateSignatureTracker,
) -> Int {
self.duplicates
}
///|
pub fn DuplicateSignatureTracker::duplicate_rate(
self : DuplicateSignatureTracker,
) -> Double {
if self.rows == 0 {
0.0
} else {
self.duplicates.to_double() / self.rows.to_double()
}
}
///|
pub fn DuplicateSignatureTracker::reset(
self : DuplicateSignatureTracker,
) -> Unit {
self.signatures.clear()
self.rows = 0
self.duplicates = 0
}