@antv/data-wizard
Version:
A js/ts library for data processing
351 lines (349 loc) • 10.8 kB
JavaScript
import { __assign, __read, __spreadArray } from "tslib";
import { assert, isArray, flatten } from '../utils';
import * as cache from './caches';
/**
* Return the minimum of the array.
* @param array - The array to process
*/
export function min(array) {
var value = cache.get(array, 'min');
if (value !== undefined) {
return value;
}
return cache.set(array, 'min', Math.min.apply(Math, __spreadArray([], __read(array))));
}
function minIdx(array) {
var min = array[0];
var idx = 0;
for (var i = 0; i < array.length; i += 1) {
if (array[i] < min) {
idx = i;
min = array[i];
}
}
return idx;
}
/**
* Return the minimum index of the array.
* @param array - The array to process
*/
export function minIndex(array) {
var value = cache.get(array, 'minIndex');
if (value !== undefined)
return value;
return cache.set(array, 'minIndex', minIdx(array));
}
/**
* Return the maximum of the array.
* @param array - The array to process
*/
export function max(array) {
var value = cache.get(array, 'max');
if (value !== undefined)
return value;
return cache.set(array, 'max', Math.max.apply(Math, __spreadArray([], __read(array))));
}
function maxIdx(array) {
var max = array[0];
var idx = 0;
for (var i = 0; i < array.length; i += 1) {
if (array[i] > max) {
idx = i;
max = array[i];
}
}
return idx;
}
/**
* Return the maximum index of the array.
* @param array - The array to process
*/
export function maxIndex(array) {
var value = cache.get(array, 'maxIndex');
if (value !== undefined)
return value;
return cache.set(array, 'maxIndex', maxIdx(array));
}
/**
* Return the sum of the array.
* @param array - The array to process
*/
export function sum(array) {
var value = cache.get(array, 'sum');
if (value !== undefined)
return value;
return cache.set(array, 'sum', array.reduce(function (prev, current) { return current + prev; }, 0));
}
/**
* Return the mean of the array.
* @param array - The array to process
*/
export function mean(array) {
return sum(array) / array.length;
}
/**
* Return the geometricMean of the array.
* @param array - The array to process
*/
export function geometricMean(array) {
assert(array.some(function (item) { return item > 0; }), 'each item in array must greater than 0');
var value = cache.get(array, 'geometricMean');
if (value !== undefined)
return value;
return cache.set(array, 'geometricMean', Math.pow(array.reduce(function (prev, curr) { return prev * curr; }, 1), (1 / array.length)));
}
/**
* Return the harmonicMean of the array.
* @param array - The array to process
*/
export function harmonicMean(array) {
var base = Math.pow(2, 16);
var value = cache.get(array, 'harmonicMean');
if (value !== undefined)
return value;
return cache.set(array, 'harmonicMean', (base * array.length) / array.reduce(function (prev, curr) { return base / curr + prev; }, 0));
}
function sort(array) {
return array.sort(function (l, r) { return (l > r ? 1 : -1); });
}
/**
* Return the median of the array.
* @param array - The array to process
*/
export function median(array, sorted) {
if (sorted === void 0) { sorted = false; }
var length = array.length;
var newArray = sorted ? array : sort(array);
if (length % 2 === 1)
return newArray[(length - 1) / 2];
return (newArray[length / 2 - 1] + newArray[length / 2]) / 2;
}
/**
* Return the quartile of the array.
* @param array - The array to process
* @param sorted - Whether it is sorted
*/
export function quartile(array, sorted) {
if (sorted === void 0) { sorted = false; }
assert(array.length >= 3, 'array.length cannot be less than 3');
var length = array.length;
var newArray = sorted ? array : sort(array);
var Q2 = median(newArray, true);
var Q1;
var Q3;
if (length % 2 === 1) {
Q1 = median(newArray.slice(0, (length - 1) / 2), true);
Q3 = median(newArray.slice((length + 1) / 2), true);
}
else {
Q1 = median(newArray.slice(0, length / 2), true);
Q3 = median(newArray.slice(length / 2), true);
}
return [Q1, Q2, Q3];
}
/**
* Return the quantile of the array.
* @param array - The array to process
* @param percent - percent
* @param sorted - Whether it is sorted
*/
export function quantile(array, percent, sorted) {
if (sorted === void 0) { sorted = false; }
assert(percent > 0 && percent < 100, 'percent cannot be between (0, 100)');
var newArray = sorted ? array : sort(array);
var index = Math.ceil((array.length * percent) / 100) - 1;
return newArray[index];
}
/**
* Return the variance of the array.
* @param array - The array to process
*/
export function variance(array) {
var m = mean(array);
var value = cache.get(array, 'variance');
if (value !== undefined)
return value;
return cache.set(array, 'variance', array.reduce(function (prev, curr) { return prev + Math.pow((curr - m), 2); }, 0) / array.length);
}
/**
* Return the standard deviation of the array.
* @param array - The array to process
*/
export function standardDeviation(array) {
return Math.sqrt(variance(array));
}
/**
* Return the coefficient of variance of the array.
* @param array - The array to process
*/
export function coefficientOfVariance(array) {
var stdev = standardDeviation(array);
var arrayMean = mean(array);
return stdev / arrayMean;
}
/**
* Return the covariance of the array.
* @param array - The array to process
*/
export function covariance(x, y) {
assert(x.length === y.length, 'x and y must has same length');
var exy = mean(x.map(function (item, i) { return item * y[i]; }));
return exy - mean(x) * mean(y);
}
/**
* Return the Pearson CorrelationCoefficient of two array.
*/
export function pearson(x, y) {
var cov = covariance(x, y);
var dx = standardDeviation(x);
var dy = standardDeviation(y);
return cov / (dx * dy);
}
/**
* Return the counts of valid value in the array.
* @param array - The array to process
*/
export function valid(array) {
var count = 0;
for (var i = 0; i < array.length; i += 1) {
if (array[i])
count += 1;
}
return count;
}
/**
* Return the counts of missing value in the array.
* @param array - The array to process
*/
export function missing(array) {
return array.length - valid(array);
}
/**
* Return the counts of each distinct value in the array.
* @param array - The array to process
*/
export function valueMap(array) {
var data = {};
array.forEach(function (value) {
if (data[value])
data[value] += 1;
else
data[value] = 1;
});
return data;
}
/**
* Return the counts of distinct value in the array.
* @param array - The array to process
*/
export function distinct(array) {
return Object.keys(valueMap(array)).length;
}
/**
* Return the sum of the array by specific measure.
* @param array - The array to process
* @param measure - The selected measure
*/
export function sumBy(array, measure) {
return array.map(function (val) { return val[measure]; }).reduce(function (acc, val) { return acc + val; }, 0);
}
/**
* Return the count of the array by specific measure.
* @param array - The array to process
* @param measure - The selected measure
*/
export function countBy(array, measure) {
return array.filter(function (item) { return measure in item; }).length;
}
/**
* Return the maximum of the array by specific measure.
* @param array - The array to process
* @param measure - The selected measure
*/
export function maxBy(array, measure) {
return Math.max.apply(Math, __spreadArray([], __read(array.map(function (val) { return val[measure]; }))));
}
/**
* Return the minimum of the array by specific measure.
* @param array - The array to process
* @param measure - The selected measure
*/
export function minBy(array, measure) {
return Math.min.apply(Math, __spreadArray([], __read(array.map(function (val) { return val[measure]; }))));
}
/**
* Return the mean of the array by specific measure.
* @param array - The array to process
* @param measure - The selected measure
*/
export function meanBy(array, measure) {
return array.map(function (val) { return val[measure]; }).reduce(function (acc, val) { return acc + val; }, 0) / array.length;
}
/**
* Return the groups of the array.
* @param array - The array to process
* @param measure - The selected measure
*/
export function groupBy(array, measure) {
var iter = function (_a) {
var _b = measure, prop = _a[_b];
return prop;
};
var dataArray = isArray(array) ? array : Object.values(array);
return dataArray.reduce(function (result, item) {
var _a;
var id = iter(item);
if (!result[id]) {
Object.assign(result, (_a = {}, _a[id] = [], _a));
}
result[id].push(item);
return result;
}, {});
}
export var AggregatorMap = {
SUM: sumBy,
COUNT: countBy,
MAX: maxBy,
MIN: minBy,
MEAN: meanBy,
};
/**
* Aggregate data via different aggregation methods
* @param array - The array to process
* @param dimensionField - The selected dimensions
* @param measure - The selected measure
* @param aggMethod - The selected aggregation method
* @param seriesField - The selected series
* @returns
*/
export function aggregate(array, dimensionField, measure, aggMethod, seriesField) {
if (aggMethod === void 0) { aggMethod = 'SUM'; }
var grouped = groupBy(array, dimensionField);
var aggregator = AggregatorMap[aggMethod];
if (!seriesField) {
return Object.entries(grouped).map(function (_a) {
var _b;
var _c = __read(_a, 2), value = _c[0], dataGroup = _c[1];
return _b = {},
_b[dimensionField] = value,
_b[measure] = aggregator(dataGroup, measure),
_b;
});
}
return flatten(Object.entries(grouped).map(function (_a) {
var _b = __read(_a, 2), value = _b[0], dataGroup = _b[1];
var childGrouped = groupBy(dataGroup, seriesField);
var part = Object.entries(childGrouped).map(function (_a) {
var _b;
var _c = __read(_a, 2), childValue = _c[0], childDataGroup = _c[1];
return _b = {},
_b[seriesField] = childValue,
_b[measure] = sumBy(childDataGroup, measure),
_b;
});
return part.map(function (item) {
var _a;
return __assign(__assign({}, item), (_a = {}, _a[dimensionField] = value, _a));
});
}));
}