danfojs
Version:
JavaScript library providing high performance, intuitive, and easy to use data structures for manipulating and processing structured data.
1,374 lines (1,372 loc) • 59.6 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @license
* Copyright 2022 JsData. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ==========================================================================
*/
var dummy_encoder_1 = __importDefault(require("../transformers/encoders/dummy.encoder"));
var mathjs_1 = require("mathjs");
var tensorflowlib_1 = __importDefault(require("../shared/tensorflowlib"));
var defaults_1 = require("../shared/defaults");
var math_ops_1 = require("./math.ops");
var errors_1 = __importDefault(require("../shared/errors"));
var indexing_1 = require("./indexing");
var utils_1 = __importDefault(require("../shared/utils"));
var generic_1 = __importDefault(require("./generic"));
var table_1 = require("table");
var strings_1 = __importDefault(require("./strings"));
var datetime_1 = __importDefault(require("./datetime"));
var plotting_1 = require("../../danfojs-base/plotting");
var utils = new utils_1.default();
/**
* One-dimensional ndarray with axis labels.
* The object supports both integer- and label-based indexing and provides a host of methods for performing operations involving the index.
* Operations between Series (+, -, /, , *) align values based on their associated index values – they need not be the same length.
* @param data 1D Array, JSON, Tensor, Block of data.
* @param options.index Array of numeric or string index for subseting array. If not specified, indices are auto generated.
* @param options.columns Column name. This is like the name of the Series. If not specified, column name is set to 0.
* @param options.dtypes Data types of the Series data. If not specified, dtypes is inferred.
* @param options.config General configuration object for extending or setting Series behavior.
*/
var Series = /** @class */ (function (_super) {
__extends(Series, _super);
function Series(data, options) {
if (data === void 0) { data = []; }
if (options === void 0) { options = {}; }
var _this = this;
var index = options.index, columns = options.columns, dtypes = options.dtypes, config = options.config;
if (Array.isArray(data[0]) || utils.isObject(data[0])) {
data = utils.convert2DArrayToSeriesArray(data);
_this = _super.call(this, {
data: data,
index: index,
columns: columns,
dtypes: dtypes,
config: config,
isSeries: true
}) || this;
}
else {
_this = _super.call(this, {
data: data,
index: index,
columns: columns,
dtypes: dtypes,
config: config,
isSeries: true
}) || this;
}
return _this;
}
/**
* Purely integer-location based indexing for selection by position.
* ``.iloc`` is primarily integer position based (from ``0`` to
* ``length-1`` of the axis), but may also be used with a boolean array.
*
* @param rows Array of row indexes
*
* Allowed inputs are in rows and columns params are:
*
* - An array of single integer, e.g. ``[5]``.
* - A list or array of integers, e.g. ``[4, 3, 0]``.
* - A slice array string with ints, e.g. ``["1:7"]``.
* - A boolean array.
* - A ``callable`` function with one argument (the calling Series or
* DataFrame) and that returns valid output for indexing (one of the above).
* This is useful in method chains, when you don't have a reference to the
* calling object, but would like to base your selection on some value.
*
* ``.iloc`` will raise ``IndexError`` if a requested indexer is
* out-of-bounds.
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6], { index: ['a', 'b', 'c', 'd', 'e', 'f'] });
* const sf2 = sf.iloc([0, 2, 4]);
* sf2.print();
* ```
*/
Series.prototype.iloc = function (rows) {
return (0, indexing_1._iloc)({ ndFrame: this, rows: rows });
};
/**
* Access a group of rows by label(s) or a boolean array.
* ``loc`` is primarily label based, but may also be used with a boolean array.
*
* @param rows Array of row indexes
*
* Allowed inputs are:
*
* - A single label, e.g. ``["5"]`` or ``['a']``, (note that ``5`` is interpreted as a
* *label* of the index, and **never** as an integer position along the index).
*
* - A list or array of labels, e.g. ``['a', 'b', 'c']``.
*
* - A slice object with labels, e.g. ``["a:f"]``. Note that start and the stop are included
*
* - A boolean array of the same length as the axis being sliced,
* e.g. ``[True, False, True]``.
*
* - A ``callable`` function with one argument (the calling Series or
* DataFrame) and that returns valid output for indexing (one of the above)
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6], { index: ['a', 'b', 'c', 'd', 'e', 'f'] });
* const sf2 = sf.loc(['a', 'c', 'e']);
* sf2.print();
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6], { index: ['a', 'b', 'c', 'd', 'e', 'f'] });
* const sf2 = sf.loc(sf.gt(2));
* sf2.print();
* ```
*/
Series.prototype.loc = function (rows) {
return (0, indexing_1._loc)({ ndFrame: this, rows: rows });
};
/**
* Returns the first n values in a Series
* @param rows The number of rows to return
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6], { index: ['a', 'b', 'c', 'd', 'e', 'f'] });
* const sf2 = sf.head(3);
* sf2.print();
* ```
*/
Series.prototype.head = function (rows) {
if (rows === void 0) { rows = 5; }
if (rows <= 0) {
throw new Error("ParamError: Number of rows cannot be less than 1");
}
if (this.shape[0] <= rows) {
return this.copy();
}
if (this.shape[0] - rows < 0) {
throw new Error("ParamError: Number of rows cannot be greater than available rows in data");
}
return this.iloc(["0:" + rows]);
};
/**
* Returns the last n values in a Series
* @param rows The number of rows to return
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6], { index: ['a', 'b', 'c', 'd', 'e', 'f'] });
* const sf2 = sf.tail(3);
* sf2.print();
* ```
*/
Series.prototype.tail = function (rows) {
if (rows === void 0) { rows = 5; }
if (rows <= 0) {
throw new Error("ParamError: Number of rows cannot be less than 1");
}
if (this.shape[0] <= rows) {
return this.copy();
}
if (this.shape[0] - rows < 0) {
throw new Error("ParamError: Number of rows cannot be greater than available rows in data");
}
var startIdx = this.shape[0] - rows;
return this.iloc([startIdx + ":"]);
};
/**
* Returns specified number of random rows in a Series
* @param num The number of rows to return
* @param options.seed An integer specifying the random seed that will be used to create the distribution.
* @example
* ```
* const df = new Series([1, 2, 3, 4])
* const df2 = await df.sample(2)
* df2.print()
* ```
* @example
* ```
* const df = new Series([1, 2, 3, 4])
* const df2 = await df.sample(1, { seed: 1 })
* df2.print()
* ```
*/
Series.prototype.sample = function (num, options) {
if (num === void 0) { num = 5; }
return __awaiter(this, void 0, void 0, function () {
var seed, shuffledIndex, sf;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
seed = __assign({ seed: 1 }, options).seed;
if (num > this.shape[0]) {
throw new Error("Sample size n cannot be bigger than size of dataset");
}
if (num < -1 || num == 0) {
throw new Error("Sample size cannot be less than -1 or be equal to 0");
}
num = num === -1 ? this.shape[0] : num;
return [4 /*yield*/, tensorflowlib_1.default.data.array(this.index).shuffle(num, "" + seed).take(num).toArray()];
case 1:
shuffledIndex = _a.sent();
sf = this.iloc(shuffledIndex);
return [2 /*return*/, sf];
}
});
});
};
Series.prototype.add = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("add");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "add" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
Series.prototype.sub = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("sub");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "sub" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
Series.prototype.mul = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("mul");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "mul" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
Series.prototype.div = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("div");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "div" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
Series.prototype.pow = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("pow");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "pow" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
Series.prototype.mod = function (other, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("mod");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "mod" });
if (inplace) {
this.$setValues(newData);
}
else {
return utils.createNdframeFromNewDataWithOldProps({ ndFrame: this, newData: newData, isSeries: true });
}
};
/**
* Checks if the array value passed has a compatible dtype, removes NaN values, and if
* boolean values are present, converts them to integer values.
*/
Series.prototype.$checkAndCleanValues = function (values, operation) {
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError(operation);
values = utils.removeMissingValuesFromArray(values);
if (this.dtypes[0] == "boolean") {
values = utils.mapBooleansToIntegers(values, 1);
}
return values;
};
/**
* Returns the mean of elements in Series.
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.mean());
* //output 3.5
* ```
*/
Series.prototype.mean = function () {
var values = this.$checkAndCleanValues(this.values, "mean");
return (values.reduce(function (a, b) { return a + b; }) / values.length);
};
/**
* Returns the median of elements in Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.median());
* //output 3.5
* ```
*/
Series.prototype.median = function () {
var values = this.$checkAndCleanValues(this.values, "median");
return (0, mathjs_1.median)(values);
};
/**
* Returns the modal value of elements in Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 4, 5, 6]);
* console.log(sf.mode());
* //output [ 4 ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 4, 5, 5, 6]);
* console.log(sf.mode());
* //output [ 4, 5 ]
* ```
*
*/
Series.prototype.mode = function () {
var values = this.$checkAndCleanValues(this.values, "mode");
return (0, mathjs_1.mode)(values);
};
/**
* Returns the minimum value in a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.min());
* //output 1
* ```
*
*/
Series.prototype.min = function () {
var values = this.$checkAndCleanValues(this.values, "min");
var smallestValue = values[0];
for (var i = 0; i < values.length; i++) {
smallestValue = smallestValue < values[i] ? smallestValue : values[i];
}
return smallestValue;
};
/**
* Returns the maximum value in a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.max());
* //output 6
* ```
*/
Series.prototype.max = function () {
var values = this.$checkAndCleanValues(this.values, "max");
var biggestValue = values[0];
for (var i = 0; i < values.length; i++) {
biggestValue = biggestValue > values[i] ? biggestValue : values[i];
}
return biggestValue;
};
/**
* Return the sum of the values in a series.
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.sum());
* //output 21
* ```
*/
Series.prototype.sum = function () {
var values = this.$checkAndCleanValues(this.values, "sum");
return values.reduce(function (sum, value) { return sum + value; }, 0);
};
/**
* Return number of non-null elements in a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.count());
* //output 6
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6, NaN]);
* console.log(sf.count());
* //output 6
* ```
*/
Series.prototype.count = function () {
var values = utils.removeMissingValuesFromArray(this.values);
return values.length;
};
/**
* Return maximum of series and other.
* @param other Series, number or Array of numbers to check against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.maximum(3);
* console.log(sf2.values);
* //output [ 3, 3, 3, 4, 5, 6 ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = new Series([4, 1, 3, 40, 5, 3]);
* const sf3 = sf.maximum(sf2);
* console.log(sf3.values);
* //output [ 4, 2, 3, 40, 5, 6 ]
* ```
*/
Series.prototype.maximum = function (other) {
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("maximum");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "maximum" });
return new Series(newData, {
columns: this.columns,
index: this.index
});
};
/**
* Return minimum of series and other.
* @param other Series, number of Array of numbers to check against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.minimum(3);
* console.log(sf2.values);
* //output [ 1, 2, 3, 3, 3, 3 ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = new Series([4, 1, 3, 40, 5, 3]);
* const sf3 = sf.minimum(sf2);
* console.log(sf3.values);
* //output [ 1, 1, 3, 4, 5, 3 ]
* ```
*
*/
Series.prototype.minimum = function (other) {
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("maximum");
var newData = (0, math_ops_1._genericMathOp)({ ndFrame: this, other: other, operation: "minimum" });
return new Series(newData, {
columns: this.columns,
index: this.index
});
};
Series.prototype.round = function (dp, options) {
if (dp === void 0) { dp = 1; }
var inplace = __assign({ inplace: false }, options).inplace;
if (dp === undefined)
dp = 1;
var newValues = utils.round(this.values, dp, true);
if (inplace) {
this.$setValues(newValues);
}
else {
return utils.createNdframeFromNewDataWithOldProps({
ndFrame: this,
newData: newValues,
isSeries: true
});
}
};
/**
* Return sample standard deviation of elements in Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.std());
* //output 1.8708286933869707
* ```
*/
Series.prototype.std = function () {
var values = this.$checkAndCleanValues(this.values, "max");
return (0, mathjs_1.std)(values);
};
/**
* Return unbiased variance of elements in a Series.
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* console.log(sf.var());
* //output 3.5
* ```
*/
Series.prototype.var = function () {
var values = this.$checkAndCleanValues(this.values, "max");
return (0, mathjs_1.variance)(values);
};
/**
* Return a boolean same-sized object indicating where elements are NaN.
* NaN and undefined values gets mapped to true, and everything else gets mapped to false.
* @example
* ```
* const sf = new Series([1, 2, 3, 4, NaN, 6]);
* console.log(sf.isNaN());
* //output [ false, false, false, false, true, false ]
* ```
*
*/
Series.prototype.isNa = function () {
var newData = this.values.map(function (value) {
if (utils.isEmpty(value)) {
return true;
}
else {
return false;
}
});
var sf = new Series(newData, {
index: this.index,
dtypes: ["boolean"],
config: this.config
});
return sf;
};
Series.prototype.fillNa = function (value, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (!value && typeof value !== "boolean" && typeof value !== "number") {
throw Error('ParamError: value must be specified');
}
var newValues = [];
this.values.forEach(function (val) {
if (utils.isEmpty(val)) {
newValues.push(value);
}
else {
newValues.push(val);
}
});
if (inplace) {
this.$setValues(newValues);
}
else {
return utils.createNdframeFromNewDataWithOldProps({
ndFrame: this,
newData: newValues,
isSeries: true
});
}
};
Series.prototype.sortValues = function (options) {
var _a = __assign({ ascending: true, inplace: false }, options), ascending = _a.ascending, inplace = _a.inplace;
var sortedValues = [];
var sortedIndex = [];
var rangeIdx = utils.range(0, this.index.length - 1);
var sortedIdx = utils.sortArrayByIndex(rangeIdx, this.values, this.dtypes[0]);
for (var _i = 0, sortedIdx_1 = sortedIdx; _i < sortedIdx_1.length; _i++) {
var indx = sortedIdx_1[_i];
sortedValues.push(this.values[indx]);
sortedIndex.push(this.index[indx]);
}
if (ascending) {
sortedValues = sortedValues.reverse();
sortedIndex = sortedIndex.reverse();
}
if (inplace) {
this.$setValues(sortedValues);
this.$setIndex(sortedIndex);
}
else {
var sf = new Series(sortedValues, {
index: sortedIndex,
dtypes: this.dtypes,
config: this.config
});
return sf;
}
};
/**
* Makes a deep copy of a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.copy();
* ```
*
*/
Series.prototype.copy = function () {
var sf = new Series(__spreadArray([], this.values, true), {
columns: __spreadArray([], this.columns, true),
index: __spreadArray([], this.index, true),
dtypes: __spreadArray([], this.dtypes, true),
config: __assign({}, this.config)
});
return sf;
};
/**
* Generate descriptive statistics.
* Descriptive statistics include those that summarize the central tendency,
* dispersion and shape of a dataset’s distribution, excluding NaN values.
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.describe();
* sf2.print();
* ```
*/
Series.prototype.describe = function () {
if (this.dtypes[0] == "string") {
throw new Error("DType Error: Cannot generate descriptive statistics for Series with string dtype");
}
else {
var index = ['count', 'mean', 'std', 'min', 'median', 'max', 'variance'];
var count = this.count();
var mean = this.mean();
var std_1 = this.std();
var min = this.min();
var median_1 = this.median();
var max = this.max();
var variance_1 = this.var();
var data = [count, mean, std_1, min, median_1, max, variance_1];
var sf = new Series(data, { index: index });
return sf;
}
};
Series.prototype.resetIndex = function (options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (inplace) {
this.$resetIndex();
}
else {
var sf = this.copy();
sf.$resetIndex();
return sf;
}
};
Series.prototype.setIndex = function (index, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (!index) {
throw Error('Param Error: Must specify index array');
}
if (inplace) {
this.$setIndex(index);
}
else {
var sf = this.copy();
sf.$setIndex(index);
return sf;
}
};
Series.prototype.map = function (callable, options) {
var inplace = __assign({ inplace: false }, options).inplace;
var isCallable = utils.isFunction(callable);
var data = this.values.map(function (val, i) {
if (isCallable) {
return callable(val, i);
}
else if (utils.isObject(callable)) {
if (val in callable) {
//@ts-ignore
return callable[val];
}
else {
return val;
}
}
else {
throw new Error("Param Error: callable must either be a function or an object");
}
});
if (inplace) {
this.$setValues(data);
}
else {
var sf = this.copy();
sf.$setValues(data);
return sf;
}
};
Series.prototype.apply = function (callable, options) {
var inplace = __assign({ inplace: false }, options).inplace;
var isCallable = utils.isFunction(callable);
if (!isCallable) {
throw new Error("Param Error: callable must be a function");
}
var data = this.values.map(function (val) {
return callable(val);
});
if (inplace) {
this.$setValues(data);
}
else {
var sf = this.copy();
sf.$setValues(data);
return sf;
}
};
/**
* Returns a Series with only the unique value(s) in the original Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
* const sf2 = sf.unique();
* console.log(sf2.values);
* //output [ 1, 2, 3, 4, 5, 6 ]
* ```
*/
Series.prototype.unique = function () {
var newValues = new Set(this.values);
var series = new Series(Array.from(newValues));
return series;
};
/**
* Return the number of unique elements in a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
* console.log(sf.nUnique());
* //output 6
* ```
*
*/
Series.prototype.nUnique = function () {
return (new Set(this.values)).size;
};
/**
* Returns unique values and their counts in a Series
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]);
* const sf2 = sf.valueCounts();
* sf2.print();
* ```
*/
Series.prototype.valueCounts = function () {
var sData = this.values;
var dataDict = {};
for (var i = 0; i < sData.length; i++) {
var val = sData[i];
if ("" + val in dataDict) {
dataDict["" + val] = dataDict["" + val] + 1;
}
else {
dataDict["" + val] = 1;
}
}
var index = Object.keys(dataDict).map(function (x) {
return parseInt(x) ? parseInt(x) : x;
});
var data = Object.values(dataDict);
var series = new Series(data, { index: index });
return series;
};
Series.prototype.abs = function (options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError("abs");
var newValues;
newValues = this.values.map(function (val) { return Math.abs(val); });
if (inplace) {
this.$setValues(newValues);
}
else {
var sf = this.copy();
sf.$setValues(newValues);
return sf;
}
};
Series.prototype.cumSum = function (options) {
var ops = __assign({ inplace: false }, options);
return this.cumOps("sum", ops);
};
Series.prototype.cumMin = function (options) {
var ops = __assign({ inplace: false }, options);
return this.cumOps("min", ops);
};
Series.prototype.cumMax = function (options) {
var ops = __assign({ inplace: false }, options);
return this.cumOps("max", ops);
};
Series.prototype.cumProd = function (options) {
var ops = __assign({ inplace: false }, options);
return this.cumOps("prod", ops);
};
/**
* Internal helper function to calculate cumulative operations on series data
*/
Series.prototype.cumOps = function (ops, options) {
if (this.dtypes[0] == "string")
errors_1.default.throwStringDtypeOperationError(ops);
var inplace = options.inplace;
var sData = this.values;
var tempval = sData[0];
var data = [tempval];
for (var i = 1; i < sData.length; i++) {
var currVal = sData[i];
switch (ops) {
case "max":
if (currVal > tempval) {
data.push(currVal);
tempval = currVal;
}
else {
data.push(tempval);
}
break;
case "min":
if (currVal < tempval) {
data.push(currVal);
tempval = currVal;
}
else {
data.push(tempval);
}
break;
case "sum":
tempval = tempval + currVal;
data.push(tempval);
break;
case "prod":
tempval = tempval * currVal;
data.push(tempval);
break;
}
}
if (inplace) {
this.$setValues(data);
}
else {
return new Series(data, {
index: this.index,
config: __assign({}, this.config)
});
}
};
/**
* Returns less than of series and other. Supports element wise operations
* @param other Series, number, or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.lt(3);
* console.log(sf2.values);
* //output [ true, true, false, false, false, false ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.lt([3, 4, 5, 6, 7, 8]);
* console.log(sf2.values);
* //output [ true, true, false, false, false, false ]
* ```
*/
Series.prototype.lt = function (other) {
return this.boolOps(other, "lt");
};
/**
* Returns Greater than of series and other. Supports element wise operations
* @param other Series, number or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.gt(3);
* console.log(sf2.values);
* //output [ false, false, true, true, true, true ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.gt([3, 4, 5, 6, 7, 8]);
* console.log(sf2.values);
* //output [ false, false, true, true, true, true ]
* ```
*/
Series.prototype.gt = function (other) {
return this.boolOps(other, "gt");
};
/**
* Returns Less than or Equal to of series and other. Supports element wise operations
* @param other Series, number or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.le(3);
* console.log(sf2.values);
* //output [ true, true, true, true, false, false ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.le([3, 4, 5, 6, 7, 8]);
* console.log(sf2.values);
* //output [ true, true, true, true, false, false ]
* ```
*
*/
Series.prototype.le = function (other) {
return this.boolOps(other, "le");
};
/**
* Returns Greater than or Equal to of series and other. Supports element wise operations
* @param other Series, number or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.ge(3);
* console.log(sf2.values);
* //output [ false, false, true, true, true, true ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.ge([3, 4, 5, 6, 7, 8]);
* console.log(sf2.values);
* //output [ false, false, true, true, true, true ]
* ```
*/
Series.prototype.ge = function (other) {
return this.boolOps(other, "ge");
};
/**
* Returns Not Equal to of series and other. Supports element wise operations
* @param other Series, number or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.ne(3);
* console.log(sf2.values);
* //output [ true, true, false, true, true, true ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.ne([3, 2, 5, 6, 7, 8]);
* console.log(sf2.values);
* //output [ true, false, true, true, true, true ]
* ```
*
*/
Series.prototype.ne = function (other) {
return this.boolOps(other, "ne");
};
/**
* Returns Equal to of series and other. Supports element wise operations
* @param other Series, number or Array of numbers to compare against
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.eq(3);
* console.log(sf2.values);
* //output [ false, false, true, false, false, false ]
* ```
*
* @example
* ```
* const sf = new Series([1, 2, 3, 4, 5, 6]);
* const sf2 = sf.eq(new Series([3, 2, 5, 6, 7, 8]));
* console.log(sf2.values);
* //output [ false, true, false, false, false, false ]
* ```
*/
Series.prototype.eq = function (other) {
return this.boolOps(other, "eq");
};
/**
* Internal function to perform boolean operations
* @param other Other Series or number to compare with
* @param bOps Name of operation to perform [ne, ge, le, gt, lt, eq]
*/
Series.prototype.boolOps = function (other, bOps) {
var data = [];
var lSeries = this.values;
var rSeries;
if (typeof other == "number") {
rSeries = Array(this.values.length).fill(other); //create array of repeated value for broadcasting
}
else if (typeof other == "string" && ["eq", "ne"].includes(bOps)) {
rSeries = Array(this.values.length).fill(other);
}
else if (other instanceof Series) {
rSeries = other.values;
}
else if (Array.isArray(other)) {
rSeries = other;
}
else {
throw new Error("ParamError: value for other not supported. It must be either a scalar, Array or Series");
}
if (!(lSeries.length === rSeries.length)) {
throw new Error("LengthError: length of other must be equal to length of Series");
}
for (var i = 0; i < lSeries.length; i++) {
var lVal = lSeries[i];
var rVal = rSeries[i];
var bool = null;
switch (bOps) {
case "lt":
bool = lVal < rVal ? true : false;
data.push(bool);
break;
case "gt":
bool = lVal > rVal ? true : false;
data.push(bool);
break;
case "le":
bool = lVal <= rVal ? true : false;
data.push(bool);
break;
case "ge":
bool = lVal >= rVal ? true : false;
data.push(bool);
break;
case "ne":
bool = lVal !== rVal ? true : false;
data.push(bool);
break;
case "eq":
bool = lVal === rVal ? true : false;
data.push(bool);
break;
}
}
return new Series(data, {
index: this.index,
config: __assign({}, this.config)
});
};
Series.prototype.replace = function (oldValue, newValue, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (typeof oldValue === 'number' && isNaN(oldValue)) {
throw Error("Params Error: Param 'oldValue' does not support NaN. Use Series.fillNa() instead.");
}
if (!oldValue && typeof oldValue !== 'boolean' && typeof oldValue !== 'number' && typeof oldValue !== 'string') {
throw Error("Params Error: Must specify param 'oldValue' to replace");
}
if (!newValue && typeof newValue !== 'boolean' && typeof newValue !== 'number' && typeof newValue !== 'string') {
throw Error("Params Error: Must specify param 'newValue' to replace with");
}
var newArr = __spreadArray([], this.values, true).map(function (val) {
if (val === oldValue) {
return newValue;
}
else {
return val;
}
});
if (inplace) {
this.$setValues(newArr);
}
else {
var sf = this.copy();
sf.$setValues(newArr);
return sf;
}
};
Series.prototype.dropNa = function (options) {
var inplace = __assign({ inplace: false }, options).inplace;
var oldValues = this.values;
var oldIndex = this.index;
var newValues = [];
var newIndex = [];
var isNaVals = this.isNa().values;
isNaVals.forEach(function (val, i) {
if (!val) {
newValues.push(oldValues[i]);
newIndex.push(oldIndex[i]);
}
});
if (inplace) {
this.$setValues(newValues, false);
this.$setIndex(newIndex);
}
else {
var sf = this.copy();
sf.$setValues(newValues, false);
sf.$setIndex(newIndex);
return sf;
}
};
/**
* Returns the integer indices that would sort the Series.
* @param ascending Boolean indicating whether to sort in ascending order or not. Defaults to true
* @example
* ```
* const sf = new Series([3, 1, 2]);
* const sf2 = sf.argSort();
* console.log(sf2.values);
* //output [ 1, 2, 0 ]
* ```
*
* @example
* ```
* const sf = new Series([3, 1, 2]);
* const sf2 = sf.argSort({ascending: false});
* console.log(sf2.values);
* //output [ 0, 2, 1 ]
*
*/
Series.prototype.argSort = function (options) {
var ascending = __assign({ ascending: true }, options).ascending;
var sortedIndex = this.sortValues({ ascending: ascending });
var sf = new Series(sortedIndex.index);
return sf;
};
/**
* Returns integer position of the largest value in the Series.
* @example
* ```
* const sf = new Series([3, 1, 2]);
* const sf2 = sf.argMax();
* console.log(sf2);
* //output 0
* ```
*
*/
Series.prototype.argMax = function () {
return this.tensor.argMax().arraySync();
};
/**
* Returns integer position of the smallest value in the Series.
* @example
* ```
* const sf = new Series([3, 1, 2]);
* const sf2 = sf.argMin();
* console.log(sf2);
* //output 1
* ```
*
*/
Series.prototype.argMin = function () {
return this.tensor.argMin().arraySync();
};
Series.prototype.dropDuplicates = function (options) {
var _a = __assign({ keep: "first", inplace: false }, options), keep = _a.keep, inplace = _a.inplace;
if (!(["first", "last"].includes(keep))) {
throw Error("Params Error: Keep must be one of 'first' or 'last'");
}
var dataArr;
var newArr = [];
var oldIndex;
var newIndex = [];
if (keep === "last") {
dataArr = this.values.reverse();
oldIndex = this.index.reverse();
}
else {
dataArr = this.values;
oldIndex = this.index;
}
dataArr.forEach(function (val, i) {
if (!newArr.includes(val)) {
newIndex.push(oldIndex[i]);
newArr.push(val);
}
});
if (keep === "last") {
//re-reversed the array and index to its true order
newArr = newArr.reverse();
newIndex = newIndex.reverse();
}
if (inplace) {
this.$setValues(newArr, false);
this.$setIndex(newIndex);
}
else {
var sf = this.copy();
sf.$setValues(newArr, false);
sf.$setIndex(newIndex);
return sf;
}
};
Series.prototype.asType = function (dtype, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (!dtype) {
throw Error("Param Error: Please specify dtype to cast to");
}
if (!(defaults_1.DATA_TYPES.includes(dtype))) {
throw Error("dtype " + dtype + " not supported. dtype must be one of " + defaults_1.DATA_TYPES);
}
var oldValues = __spreadArray([], this.values, true);
var newValues = [];
switch (dtype) {
case "float32":
oldValues.forEach(function (val) {
newValues.push(Number(val));
});
break;
case "int32":
oldValues.forEach(function (val) {
newValues.push(parseInt(val));
});
break;
case "string":
oldValues.forEach(function (val) {
newValues.push(String(val));
});
break;
case "boolean":
oldValues.forEach(function (val) {
newValues.push(Boolean(val));
});
break;
case "undefined":
oldValues.forEach(function (_) {
newValues.push(NaN);
});
break;
default:
break;
}
if (inplace) {
this.$setValues(newValues, false);
this.$setDtypes([dtype]);
}
else {
var sf = this.copy();
sf.$setValues(newValues, false);
sf.$setDtypes([dtype]);
return sf;
}
};
Series.prototype.append = function (newValue, index, options) {
var inplace = __assign({ inplace: false }, options).inplace;
if (!newValue && typeof newValue !== "boolean" && typeof newValue !== "number") {
throw Error("Param Error: newValue cannot be null or undefined");
}
if (!index) {
throw Error("Param Error: index cannot be null or undefined");
}
var newData = __spreadArray([], this.values, true);
var newIndx = __spreadArray([], this.index, true);
if (Array.isArray(newValue) && Array.isArray(index)) {
if (newValue.length !== index.length) {
throw Error("Param Error: Length of new values and index must be the same");
}
newValue.forEach(function (el, i) {
newData.push(el);
newIndx.push(index[i]);
});
}
else if (newValue instanceof Series) {
var _value = newValue.values;
if (!Array.isArray(index)) {
throw Error("Param Error: index must be an array");
}
if (index.length !== _value.length) {
throw Error("Param Error: Length of new values and index must be the same");
}
_value.forEach(function (el, i) {
newData.push(el);
newIndx.push(index[i]);
});
}
else {
newData.push(newValue);
newIndx.push(index);
}
if (inplace) {
this.$setValues(newData, false);
this.$setIndex(newIndx);
}
else {
var sf = new Series(newData, {