data-forge
Version:
JavaScript data transformation and analysis toolkit inspired by Pandas and LINQ.
1,357 lines (1,355 loc) • 171 kB
TypeScript
import { IIndex } from './index';
import { IDataFrame } from './dataframe';
/**
* Used to configure a series.
*/
export interface ISeriesConfig<IndexT, ValueT> {
/**
* Values to put in the dataframe.
* This should be array or iterable of JavaScript values.
*/
values?: Iterator<ValueT> | Iterable<ValueT>;
/***
* The index for the serires.
* If omitted the index will default to a 0-based index.
*/
index?: Iterator<IndexT> | Iterable<IndexT>;
/**
* Array or iterable of index,value pairs to put in the series.
* If index and values are not separately specified they can be extracted
* from the pairs.
*/
pairs?: Iterator<[IndexT, ValueT]> | Iterable<[IndexT, ValueT]>;
/***
* Set to true when the series has been baked into memory
* and does not need to be lazily evaluated.
*/
baked?: boolean;
}
/**
* A user-defined callback function that can be applied to each value.
*/
export declare type CallbackFn<ValueT> = (value: ValueT, index: number) => void;
/**
* A user-defined selector function.
* Transforms a value into another kind of value.
*/
export declare type SelectorWithIndexFn<FromT, ToT> = (value: FromT, index: number) => ToT;
/**
* User-defined zipper functions.
* Used to 'zip together' multiple series or dataframes.
*/
export declare type ZipNFn<ValueT, ReturnT> = (input: ISeries<number, ValueT>) => ReturnT;
export declare type Zip2Fn<T1, T2, ReturnT> = (a: T1, b: T2) => ReturnT;
export declare type Zip3Fn<T1, T2, T3, ReturnT> = (a: T1, b: T2, c: T3) => ReturnT;
export declare type Zip4Fn<T1, T2, T3, T4, ReturnT> = (a: T1, b: T2, c: T3, d: T4) => ReturnT;
export declare type Zip5Fn<T1, T2, T3, T4, T5, ReturnT> = (a: T1, b: T2, c: T3, d: T4) => ReturnT;
/**
* A user-defined selector function with no index.
* Transforms a value into another kind of value.
*/
export declare type SelectorFn<FromT, ToT> = (value: FromT) => ToT;
/**
* A user-defined function that joins two values and produces a result.
*/
export declare type JoinFn<ValueT1, ValueT2, ResultT> = (a: ValueT1, b: ValueT2) => ResultT;
/**
* A user-defined predicate function, returns true or false based on input.
*/
export declare type PredicateFn<ValueT> = (value: ValueT) => boolean;
/**
* A user-defined function that aggregtates a value into an accumulator
* and returns the new result.
*/
export declare type AggregateFn<ValueT, ToT> = (accum: ToT, value: ValueT) => ToT;
/**
* A user-defined comparer function that Compares to values and
* returns true (truthy) if they are equivalent or false (falsy) if not.
*/
export declare type ComparerFn<ValueT1, ValueT2> = (a: ValueT1, b: ValueT2) => boolean;
export declare type SeriesConfigFn<IndexT, ValueT> = () => ISeriesConfig<IndexT, ValueT>;
export declare type GapFillFn<ValueT, ResultT> = (a: ValueT, b: ValueT) => ResultT[];
/**
* Represents the frequency of a type in a series or dataframe.
*/
export interface ITypeFrequency {
/**
* The name of the type.
*/
Type: string;
/**
* The frequency of the type's appearance in the series or dataframe.
*/
Frequency: number;
}
/**
* Represents the frequency of a value in a series or dataframe.
*/
export interface IValueFrequency {
/**
* The value.
*/
Value: any;
/**
* The frequency of the value's appearance in the series or dataframe.
*/
Frequency: number;
}
/**
* Places a value in a bucket or range of values.
*
* WARNING: This interface is deprecated and will be removed in the future.
*/
export interface IBucket {
/**
* The bucketed value.
*/
Value: number;
/**
* The index of the bucket that contains the value.
*/
Bucket: number;
/**
* The minimum value in the bucket.
*/
Min: number;
/**
* The mid-point value in the bucket.
*/
Mid: number;
/**
* The maximum value in the bucket.
*/
Max: number;
}
/**
* Specifies where from a data window the index is pulled from: the start of the window, the end or from the middle.
*/
export declare enum WhichIndex {
Start = "start",
End = "end",
}
/**
* Options to the `Series.frequency` function.
*/
export interface IFrequencyTableOptions {
/**
* Lower boundary (if defined).
*/
lower?: number;
/**
* Upper boundary (if defined).
*/
upper?: number;
/**
* Directly sets the interval (if defined). This is the range of each group.
*/
interval?: number;
/**
* Enables capturing of values for each group.
*/
captureValues?: boolean;
}
/**
* Defines a record in the frequency table output by the `Series.frequency` function.
*/
export interface IFrequencyTableEntry {
/**
* Lower value in this group of the frequency table.
*/
lower?: number;
/**
* Upper value in this group of the frequency table.
*/
upper?: number;
/**
* Count of values in this group.
*/
count: number;
/**
* Proportion (0-1) of values in this group.
*/
proportion: number;
/**
* Cumulative proportion of values in this and earlier groups.
*/
cumulative: number;
/**
* The values that were record in this group.
* (if enabled in the options).
*/
values?: number[];
}
/**
* Interface that represents a series.
* A series contains an indexed sequence of values.
* A series indexed by time is a timeseries.
*
* @typeparam IndexT The type to use for the index.
* @typeparam ValueT The type to use for each value.
*/
export interface ISeries<IndexT = number, ValueT = any> extends Iterable<ValueT> {
/**
* Get an iterator to enumerate the values of the series.
* Enumerating the iterator forces lazy evaluation to complete.
* This function is automatically called by `for...of`.
*
* @return An iterator for the values in the series.
*
* @example
* <pre>
*
* for (const value of series) {
* // ... do something with the value ...
* }
* </pre>
*/
[Symbol.iterator](): Iterator<ValueT>;
/**
* Cast the value of the series to a new type.
* This operation has no effect but to retype the values that the series contains.
*
* @return The same series, but with the type changed.
*
* @example
* <pre>
*
* const castSeries = series.cast<SomeOtherType>();
* </pre>
*/
cast<NewValueT>(): ISeries<IndexT, NewValueT>;
/**
* Get the index for the series.
*
* @return The {@link Index} for the series.
*
* @example
* <pre>
*
* const index = series.getIndex();
* </pre>
*/
getIndex(): IIndex<IndexT>;
/**
* Apply a new {@link Index} to the series.
*
* @param newIndex The new array or iterable to be the new {@link Index} of the series. Can also be a selector to choose the {@link Index} for each value in the series.
*
* @return Returns a new series with the specified {@link Index} attached.
*
* @example
* <pre>
*
* const indexedSeries = series.withIndex([10, 20, 30]);
* </pre>
*
* @example
* <pre>
*
* const indexedSeries = series.withIndex(someOtherSeries);
* </pre>
*
* @example
* <pre>
*
* const indexedSeries = series.withIndex(value => computeIndexFromValue(value));
* </pre>
*
* @example
* <pre>
*
* const indexedSeries = series.withIndex(value => value + 20);
* </pre>
*/
withIndex<NewIndexT>(newIndex: Iterable<NewIndexT> | SelectorFn<ValueT, NewIndexT>): ISeries<NewIndexT, ValueT>;
/**
* Resets the {@link Index} of the series back to the default zero-based sequential integer index.
*
* @return Returns a new series with the {@link Index} reset to the default zero-based index.
*
* @example
* <pre>
*
* const seriesWithResetIndex = series.resetIndex();
* </pre>
*/
resetIndex(): ISeries<number, ValueT>;
/**
* Merge one or more series into this series.
* Values are merged by index.
* Values at each index are combined into arrays in the resulting series.
*
* @param series... One or more other series to merge into the series.
*
* @returns The merged series.
*
* @example
* <pre>
*
* const mergedSeries = series1.merge(series2);
* </pre>
*
* <pre>
*
* const mergedSeries = series1.merge(series2, series3, etc);
* </pre>
*/
merge<MergedValueT = any>(...args: any[]): ISeries<IndexT, MergedValueT[]>;
/**
* Extract values from the series as an array.
* This forces lazy evaluation to complete.
*
* @return Returns an array of the values contained within the series.
*
* @example
* <pre>
* const values = series.toArray();
* </pre>
*/
toArray(options?: {
includeNulls?: boolean;
}): ValueT[];
/**
* Retreive the index, values pairs from the series as an array.
* Each pair is [index, value].
* This forces lazy evaluation to complete.
*
* @return Returns an array of pairs that contains the series values. Each pair is a two element array that contains an index and a value.
*
* @example
* <pre>
* const pairs = series.toPairs();
* </pre>
*/
toPairs(): ([IndexT, ValueT])[];
/**
* Convert the series to a JavaScript object.
*
* @param keySelector User-defined selector function that selects keys for the resulting object.
* @param valueSelector User-defined selector function that selects values for the resulting object.
*
* @return Returns a JavaScript object generated from the series by applying the key and value selector functions.
*
* @example
* <pre>
*
* const someObject = series.toObject(
* value => value, // Specify the value to use for field names in the output object.
* value => value // Specify the value to use as the value for each field.
* );
* </pre>
*/
toObject<KeyT = any, FieldT = any, OutT = any>(keySelector: (value: ValueT) => KeyT, valueSelector: (value: ValueT) => FieldT): OutT;
/**
* Transforms an input series, generating a new series.
* The transformer function is called for each element of the input and the collection of outputs creates the generated series.
*
* `select` is an alias for {@link Series.map}.
*
* This is the same concept as the JavaScript function `Array.map` but maps over a data series rather than an array.
*
* @param transformer A user-defined transformer function that transforms each element from the input to generate the output.
*
* @return Returns the series generated by calling the transformer function over each value in the input series.
*
* @example
* <pre>
*
* function transformer (input) {
* const output = // ... construct output from input ...
* return output;
* }
*
* const transformed = series.select(transformer);
* console.log(transformed.toString());
* </pre>
*/
select<ToT>(transformer: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
/**
* Transforms an input series, generating a new series.
* The transformer function is called for each element of the input and the collection of outputs creates the generated series.
*
* This is the same concept as the JavaScript function `Array.map` but maps over a data series rather than an array.
*
* @param transformer A user-defined transformer function that transforms each element from the input to generate the output.
*
* @return Returns a new series generated by calling the transformer function over each element of the input.
*
* @example
* <pre>
*
* function transformer (input) {
* const output = // ... construct output from input ...
* return output;
* }
*
* const transformed = series.map(transformer);
* console.log(transformed.toString());
* </pre>
*/
map<ToT>(transformer: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
/**
* Transforms and flattens an input series, generating a new series.
* The transformer function is called for each value in the input series and produces an array that is then flattened into the generated series.
*
* `selectMany` is an alias for {@link Series.flatMap}.
*
* This is the same concept as the JavaScript function `Array.flatMap` but maps over a data series rather than an array.
*
* @param transformer A user-defined function that transforms each value into an array that is then flattened into the generated series.
*
* @return Returns a new series generated by calling the transformer function over each element of the input.
*
* @example
* <pre>
*
* function transformer (input) {
* const output = [];
* while (someCondition) {
* // ... generate zero or more outputs from a single input ...
* output.push(... some generated value ...);
* }
* return output;
* }
*
* const transformed = series.selectMany(transformer);
* console.log(transformed.toString());
* </pre>
*/
selectMany<ToT>(transformer: SelectorWithIndexFn<ValueT, Iterable<ToT>>): ISeries<IndexT, ToT>;
/**
* Transforms and flattens an input series, generating a new series.
* The transformer function is called for each value in the input series and produces an array that is then flattened into the generated series.
*
* This is the same concept as the JavaScript function `Array.flatMap` but maps over a data series rather than an array.
*
* @param transformer A user-defined function that transforms each value into an array that is then flattened into the generated series.
*
* @return Returns a new series generated by calling the transformer function over each element of the input.
*
* @example
* <pre>
*
* function transformer (input) {
* const output = [];
* while (someCondition) {
* // ... generate zero or more outputs from a single input ...
* output.push(... some generated value ...);
* }
* return output;
* }
*
* const transformed = series.flatMap(transformer);
* console.log(transformed.toString());
* </pre>
*/
flatMap<ToT>(transformer: SelectorWithIndexFn<ValueT, Iterable<ToT>>): ISeries<IndexT, ToT>;
/**
* Partition a series into a {@link Series} of *data windows*.
* Each value in the new series is a chunk of data from the original series.
*
* @param period The number of values to include in each data window.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @return Returns a new series, each value of which is a chunk (data window) of the original series.
*
* @example
* <pre>
*
* const windows = series.window(2); // Get values in pairs.
* const pctIncrease = windows.select(pair => (pair.last() - pair.first()) / pair.first());
* console.log(pctIncrease.toString());
* </pre>
*
* @example
* <pre>
*
* const salesDf = ... // Daily sales data.
* const weeklySales = salesDf.window(7); // Partition up into weekly data sets.
* console.log(weeklySales.toString());
* </pre>
*/
window(period: number, whichIndex?: WhichIndex): ISeries<IndexT, ISeries<IndexT, ValueT>>;
/**
* Partition a series into a new series of *rolling data windows*.
* Each value in the new series is a rolling chunk of data from the original series.
*
* @param period The number of data values to include in each data window.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @return Returns a new series, each value of which is a rolling chunk of the original series.
*
* @example
* <pre>
*
* const salesData = ... // Daily sales data.
* const rollingWeeklySales = salesData.rollingWindow(7); // Get rolling window over weekly sales data.
* console.log(rollingWeeklySales.toString());
* </pre>
*/
rollingWindow(period: number, whichIndex?: WhichIndex): ISeries<IndexT, ISeries<IndexT, ValueT>>;
/**
* Partition a series into a new series of variable-length *data windows*
* where the divisions between the data chunks are
* defined by a user-provided *comparer* function.
*
* @param comparer Function that compares two adjacent data values and returns true if they should be in the same window.
*
* @return Returns a new series, each value of which is a chunk of data from the original series.
*
* @example
* <pre>
*
* function rowComparer (valueA, valueB) {
* if (... valueA should be in the same data window as valueB ...) {
* return true;
* }
* else {
* return false;
* }
* };
*
* const variableWindows = series.variableWindow(rowComparer);
*/
variableWindow(comparer: ComparerFn<ValueT, ValueT>): ISeries<number, ISeries<IndexT, ValueT>>;
/**
* Eliminates adjacent duplicate values.
*
* For each group of adjacent values that are equivalent only returns the last index/row for the group,
* thus ajacent equivalent values are collapsed down to the last value.
*
* @param selector Optional selector function to determine the value used to compare for equivalence.
*
* @return Returns a new series with groups of adjacent duplicate vlaues collapsed to a single value per group.
*
* @example
* <pre>
*
* const seriesWithDuplicateRowsRemoved = series.sequentialDistinct(value => value);
*
* // Or
* const seriesWithDuplicateRowsRemoved = series.sequentialDistinct(value => value.someNestedField);
* </pre>
*/
sequentialDistinct<ToT>(selector: SelectorFn<ValueT, ToT>): ISeries<IndexT, ValueT>;
/**
* Reduces the values in the series to a single result.
*
* `aggregate` is similar to {@link Series.reduce}, but the parameters are reversed.
* Please use {@link Series.reduce} in preference to `aggregate`.
*
* @param seed Optional seed value for producing the aggregation.
* @param reducer Function that takes the seed and then each value in the series and produces the reduced value.
*
* @return Returns a new value that has been reduced from the input series by passing it through the 'reducer' function.
*
* @example
* <pre>
*
* const dailySales = ... daily sales figures for the past month ...
* const totalSalesForthisMonth = dailySales.aggregate(
* 0, // Seed - the starting value.
* (accumulator, salesAmount) => accumulator + salesAmount // Aggregation function.
* );
* </pre>
*
* @example
* <pre>
*
* const previousSales = 500; // We'll seed the aggregation with this value.
* const dailySales = ... daily sales figures for the past month ...
* const updatedSales = dailySales.aggregate(
* previousSales,
* (accumulator, salesAmount) => accumulator + salesAmount
* );
* </pre>
*
* @example
* <pre>
*
* var salesDataSummary = salesData.aggregate({
* TotalSales: series => series.count(),
* AveragePrice: series => series.average(),
* TotalRevenue: series => series.sum(),
* });
* </pre>
*/
aggregate<ToT = ValueT>(seedOrSelector: AggregateFn<ValueT, ToT> | ToT, selector?: AggregateFn<ValueT, ToT>): ToT;
/**
* Reduces the values in the series to a single result.
*
* This is the same concept as the JavaScript function `Array.reduce` but reduces a data series rather than an array.
* @param reducer Function that takes the seed and then each value in the series and produces the reduced value.
* @param seed Optional initial value, if not specifed the first value in the series is used as the initial value.
*
* @return Returns a new value that has been reduced from the input series by passing it through the 'reducer' function.
*
* @example
* <pre>
*
* const dailySales = ... daily sales figures for the past month ...
* const totalSalesForthisMonth = dailySales.reduce(
* (accumulator, salesAmount) => accumulator + salesAmount, // Reducer function.
* 0 // Seed value, the starting value.
* );
* </pre>
*
* @example
* <pre>
*
* const previousSales = 500; // We'll seed the reduction with this value.
* const dailySales = ... daily sales figures for the past month ...
* const updatedSales = dailySales.reduce(
* (accumulator, salesAmount) => accumulator + salesAmount,
* previousSales
* );
* </pre>
*/
reduce<ToT = ValueT>(reducer: AggregateFn<ValueT, ToT>, seed?: ToT): ToT;
/**
* Compute the absolute range of values in each period.
* The range for each period is the absolute difference between largest (max) and smallest (min) values in that period.
*
* @param period - Period for computing the range.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the absolute range of values for each period in the original series.
*
* @example
* <pre>
*
* const closingPrice = ... series of closing prices for a particular stock ...
* const volatility = closingPrice.amountRange(5);
* </pre>
*/
amountRange(period: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* Compute the range of values in each period in proportion to the latest value.
* The range for each period is the absolute difference between largest (max) and smallest (min) values in that period.
* Proportions are expressed as 0-1 values.
*
* @param period - Period for computing the range.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the proportion change from the previous number value in the original series.
*
* @returns Returns a new series where each value indicates the proportionate range of values for each period in the original series.
*
* @example
* <pre>
*
* const closingPrice = ... series of closing prices for a particular stock ...
* const proportionVolatility = closingPrice.proportionRange(5);
* </pre>
*/
proportionRange(period: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* Compute the range of values in each period in proportion to the latest value.
* The range for each period is the absolute difference between largest (max) and smallest (min) values in that period.
* Proportions are expressed as 0-1 values.
*
* @param period - Period for computing the range.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the proportion change from the previous number value in the original series.
*
* @returns Returns a new series where each value indicates the proportionate range of values for each period in the original series.
*
* @example
* <pre>
*
* const closingPrice = ... series of closing prices for a particular stock ...
* const percentVolatility = closingPrice.percentRange(5);
* </pre>
*/
percentRange(period: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* Compute the amount of change between pairs or sets of values in the series.
*
* @param period Optional period for computing the change - defaults to 2.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the amount of change from the previous number value in the original series.
*
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const amountChanged = salesFigures.amountChanged(); // Amount that sales has changed, day to day.
* </pre>
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const amountChanged = salesFigures.amountChanged(7); // Amount that sales has changed, week to week.
* </pre>
*/
amountChange(period?: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* Compute the proportion change between pairs or sets of values in the series.
* Proportions are expressed as 0-1 values.
*
* @param period Optional period for computing the proportion - defaults to 2.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the proportion change from the previous number value in the original series.
*
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const proportionChanged = salesFigures.amountChanged(); // Proportion that sales has changed, day to day.
* </pre>
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const proportionChanged = salesFigures.amountChanged(7); // Proportion that sales has changed, week to week.
* </pre>
*/
proportionChange(period?: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* Compute the percentage change between pairs or sets of values in the series.
* Percentages are expressed as 0-100 values.
*
* @param period Optional period for computing the percentage - defaults to 2.
* @param whichIndex Sets which side of the window the index comes from: start or end. Can be "start" or "end", defaults to "end".
*
* @returns Returns a new series where each value indicates the percent change from the previous number value in the original series.
*
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const percentChanged = salesFigures.amountChanged(); // Percent that sales has changed, day to day.
* </pre>
* @example
* <pre>
*
* const saleFigures = ... running series of daily sales figures ...
* const percentChanged = salesFigures.amountChanged(7); // Percent that sales has changed, week to week.
* </pre>
*/
percentChange(period?: number, whichIndex?: WhichIndex): ISeries<IndexT, number>;
/**
* For each period, compute the proportion of values that are less than the last value in the period.
* Proportions are expressed as 0-1 values.
*
* @param period Optional period for computing the proportion rank - defaults to 2.
*
* @returns Returns a new series where each value indicates the proportion rank value for that period.
*
* @example
* <pre>
*
* const proportionRank = series.proportionRank();
* </pre>
* @example
* <pre>
*
* const proportionRank = series.proportionRank(100);
* </pre>
*/
proportionRank(period?: number): ISeries<IndexT, number>;
/**
* For each period, compute the percent of values that are less than the last value in the period.
* Percent are expressed as 0-100 values.
*
* @param period Optional period for computing the percent rank - defaults to 2.
*
* @returns Returns a new series where each value indicates the percent rank value for that period.
*
* @example
* <pre>
*
* const percentRank = series.percentRank();
* </pre>
* @example
* <pre>
*
* const percentRank = series.percentRank(100);
* </pre>
*/
percentRank(period?: number): ISeries<IndexT, number>;
/**
* Generates a cumulative sum across a series.
*
* @returns Returns a new series that is the cumulative sum of values across the input series.
*/
cumsum(): ISeries<IndexT, number>;
/**
* Skip a number of values in the series.
*
* @param numValues Number of values to skip.
*
* @return Returns a new series with the specified number of values skipped.
*
* @example
* <pre>
*
* const seriesWithRowsSkipped = series.skip(10); // Skip 10 rows in the original series.
* </pre>
*/
skip(numValues: number): ISeries<IndexT, ValueT>;
/**
* Skips values in the series while a condition evaluates to true or truthy.
*
* @param predicate Returns true/truthy to continue to skip values in the original series.
*
* @return Returns a new series with all initial sequential values removed while the predicate returned true/truthy.
*
* @example
* <pre>
*
* const seriesWithRowsSkipped = series.skipWhile(salesFigure => salesFigure > 100); // Skip initial sales figure that are less than 100.
* </pre>
*/
skipWhile(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Skips values in the series untils a condition evaluates to true or truthy.
*
* @param predicate Return true/truthy to stop skipping values in the original series.
*
* @return Returns a new series with all initial sequential values removed until the predicate returned true/truthy.
*
* @example
* <pre>
*
* const seriesWithRowsSkipped = series.skipUntil(salesFigure => salesFigure > 100); // Skip initial sales figures unitl we see one greater than 100.
* </pre>
*/
skipUntil(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Take a number of values from the series.
*
* @param numValues Number of values to take.
*
* @return Returns a new series with only the specified number of values taken from the original series.
*
* @example
* <pre>
*
* const seriesWithRowsTaken = series.take(15); // Take only the first 15 values from the original series.
* </pre>
*/
take(numRows: number): ISeries<IndexT, ValueT>;
/**
* Takes values from the series while a condition evaluates to true or truthy.
*
* @param predicate Returns true/truthy to continue to take values from the original series.
*
* @return Returns a new series with only the initial sequential values that were taken while the predicate returned true/truthy.
*
* @example
* <pre>
*
* const seriesWithRowsTaken = series.takeWhile(salesFigure => salesFigure > 100); // Take only initial sales figures that are greater than 100.
* </pre>
*/
takeWhile(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Takes values from the series until a condition evaluates to true or truthy.
*
* @param predicate Return true/truthy to stop taking values in the original series.
*
* @return Returns a new series with only the initial sequential values taken until the predicate returned true/truthy.
*
* @example
* <pre>
*
* const seriesWithRowsTaken = series.takeUntil(salesFigure => salesFigure > 100); // Take all initial sales figures until we see one that is greater than 100.
* </pre>
*/
takeUntil(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Count the number of values in the seriese
*
* @return Returns the count of all values.
*
* @example
* <pre>
*
* const numValues = series.count();
* </pre>
*/
count(): number;
/**
* Get the first value of the series.
*
* @return Returns the first value of the series.
*
* @example
* <pre>
*
* const firstValue = series.first();
* </pre>
*/
first(): ValueT;
/**
* Get the last value of the series.
*
* @return Returns the last value of the series.
*
* @example
* <pre>
*
* const lastValue = series.last();
* </pre>
*/
last(): ValueT;
/**
* Get the value, if there is one, with the specified index.
*
* @param index Index to for which to retreive the value.
*
* @return Returns the value from the specified index in the series or undefined if there is no such index in the present in the series.
*
* @example
* <pre>
*
* const value = series.at(5); // Get the value at index 5 (with a default 0-based index).
* </pre>
*
* @example
* <pre>
*
* const date = ... some date ...
* // Retreive the value with specified date from a time-series (assuming date indexed has been applied).
* const value = series.at(date);
* </pre>
*/
at(index: IndexT): ValueT | undefined;
/**
* Get X value from the start of the series.
* Pass in a negative value to get all values at the head except for X values at the tail.
*
* @param numValues Number of values to take.
*
* @return Returns a new series that has only the specified number of values taken from the start of the original series.
*
* @examples
* <pre>
*
* const sample = series.head(10); // Take a sample of 10 values from the start of the series.
* </pre>
*/
head(numValues: number): ISeries<IndexT, ValueT>;
/**
* Get X values from the end of the series.
* Pass in a negative value to get all values at the tail except X values at the head.
*
* @param numValues Number of values to take.
*
* @return Returns a new series that has only the specified number of values taken from the end of the original series.
*
* @examples
* <pre>
*
* const sample = series.tail(12); // Take a sample of 12 values from the end of the series.
* </pre>
*/
tail(numValues: number): ISeries<IndexT, ValueT>;
/**
* Filter the series using user-defined predicate function.
*
* `where` is an alias for {@link Series.filter}.
*
* This is the same concept as the JavaScript function `Array.filter` but filters a data series rather than an array.
*
* @param predicate Predicate function to filter values from the series. Returns true/truthy to keep elements, or false/falsy to omit elements.
*
* @return Returns a new series containing only the values from the original series that matched the predicate.
*
* @example
* <pre>
*
* // Filter so we only have sales figures greater than 100.
* const filtered = series.where(salesFigure => salesFigure > 100);
* console.log(filtered.toArray());
* </pre>
*/
where(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Filter the series through a user-defined predicate function.
*
* This is the same concept as the JavaScript function `Array.filter` but filters a data series rather than an array.
*
* @param predicate Predicate function to filter values from the series. Returns true/truthy to keep elements, or false/falsy to omit elements.
*
* @return Returns a new series containing only the values from the original series that matched the predicate.
*
* @example
* <pre>
*
* // Filter so we only have sales figures greater than 100.
* const filtered = series.filter(salesFigure => salesFigure > 100);
* console.log(filtered.toArray());
* </pre>
*/
filter(predicate: PredicateFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Invoke a callback function for each value in the series.
*
* @param callback The calback function to invoke for each value.
*
* @return Returns the original series with no modifications.
*
* @example
* <pre>
*
* series.forEach(value => {
* // ... do something with the value ...
* });
* </pre>
*/
forEach(callback: CallbackFn<ValueT>): ISeries<IndexT, ValueT>;
/**
* Evaluates a predicate function for every value in the series to determine
* if some condition is true/truthy for **all** values in the series.
*
* @param predicate Predicate function that receives each value. It should returns true/truthy for a match, otherwise false/falsy.
*
* @return Returns true if the predicate has returned true or truthy for every value in the series, otherwise returns false. Returns false for an empty series.
*
* @example
* <pre>
*
* const result = series.all(salesFigure => salesFigure > 100); // Returns true if all sales figures are greater than 100.
* </pre>
*/
all(predicate: PredicateFn<ValueT>): boolean;
/**
* Evaluates a predicate function for every value in the series to determine
* if some condition is true/truthy for **any** of values in the series.
*
* If no predicate is specified then it simply checks if the series contains more than zero values.
*
* @param predicate Optional predicate function that receives each value. It should return true/truthy for a match, otherwise false/falsy.
*
* @return Returns true if the predicate has returned truthy for any value in the series, otherwise returns false.
* If no predicate is passed it returns true if the series contains any values at all.
* Returns false for an empty series.
*
* @example
* <pre>
*
* const result = series.any(salesFigure => salesFigure > 100); // Do we have any sales figures greater than 100?
* </pre>
*
* @example
* <pre>
*
* const result = series.any(); // Do we have any sales figures at all?
* </pre>
*/
any(predicate?: PredicateFn<ValueT>): boolean;
/**
* Evaluates a predicate function for every value in the series to determine
* if some condition is true/truthy for **none** of values in the series.
*
* If no predicate is specified then it simply checks if the series contains zero values.
*
* @param predicate Optional predicate function that receives each value. It should return true/truthy for a match, otherwise false/falsy.
*
* @return Returns true if the predicate has returned truthy for zero values in the series, otherwise returns false. Returns false for an empty series.
*
* @example
* <pre>
*
* const result = series.none(salesFigure => salesFigure > 100); // Do we have zero sales figures greater than 100?
* </pre>
*
* @example
* <pre>
*
* const result = series.none(); // Do we have zero sales figures?
* </pre>
*/
none(predicate?: PredicateFn<ValueT>): boolean;
/**
* Gets a new series containing all values starting at or after the specified index value.
*
* @param indexValue The index value at which to start the new series.
*
* @return Returns a new series containing all values starting at or after the specified index value.
*
* @example
* <pre>
*
* const series = new Series({
* index: [0, 1, 2, 3], // This is the default index.
* values: [10, 20, 30, 40],
* });
*
* const lastHalf = series.startAt(2);
* expect(lastHalf.toArray()).to.eql([30, 40]);
* </pre>
*
* @example
* <pre>
*
* const timeSeries = ... a series indexed by date/time ...
*
* // Get all values starting at (or after) a particular date.
* const result = timeSeries.startAt(new Date(2016, 5, 4));
* </pre>
*/
startAt(indexValue: IndexT): ISeries<IndexT, ValueT>;
/**
* Gets a new series containing all values up until and including the specified index value (inclusive).
*
* @param indexValue The index value at which to end the new series.
*
* @return Returns a new series containing all values up until and including the specified index value.
*
* @example
* <pre>
*
* const series = new Series({
* index: [0, 1, 2, 3], // This is the default index.
* values: [10, 20, 30, 40],
* });
*
* const firstHalf = series.endAt(1);
* expect(firstHalf.toArray()).to.eql([10, 20]);
* </pre>
*
* @example
* <pre>
*
* const timeSeries = ... a series indexed by date/time ...
*
* // Get all values ending at a particular date.
* const result = timeSeries.endAt(new Date(2016, 5, 4));
* </pre>
*/
endAt(indexValue: IndexT): ISeries<IndexT, ValueT>;
/**
* Gets a new series containing all values up to the specified index value (exclusive).
*
* @param indexValue The index value at which to end the new series.
*
* @return Returns a new series containing all values up to (but not including) the specified index value.
*
* @example
* <pre>
*
* const series = new Series({
* index: [0, 1, 2, 3], // This is the default index.
* values: [10, 20, 30, 40],
* });
*
* const firstHalf = series.before(2);
* expect(firstHalf.toArray()).to.eql([10, 20]);
* </pre>
*
* @example
* <pre>
*
* const timeSeries = ... a series indexed by date/time ...
*
* // Get all values before the specified date.
* const result = timeSeries.before(new Date(2016, 5, 4));
* </pre>
*/
before(indexValue: IndexT): ISeries<IndexT, ValueT>;
/**
* Gets a new series containing all values after the specified index value (exclusive).
*
* @param indexValue The index value after which to start the new series.
*
* @return Returns a new series containing all values after the specified index value.
*
* @example
* <pre>
*
* const series = new Series({
* index: [0, 1, 2, 3], // This is the default index.
* values: [10, 20, 30, 40],
* });
*
* const lastHalf = df.before(1);
* expect(lastHalf.toArray()).to.eql([30, 40]);
* </pre>
*
* @example
* <pre>
*
* const timeSerie = ... a series indexed by date/time ...
*
* // Get all values after the specified date.
* const result = timeSeries.after(new Date(2016, 5, 4));
* </pre>
*/
after(indexValue: IndexT): ISeries<IndexT, ValueT>;
/**
* Gets a new series containing all values between the specified index values (inclusive).
*
* @param startIndexValue The index at which to start the new series.
* @param endIndexValue The index at which to end the new series.
*
* @return Returns a new series containing all values between the specified index values (inclusive).
*
* @example
* <pre>
*
* const series = new Series({
* index: [0, 1, 2, 3, 4, 6], // This is the default index.
* values: [10, 20, 30, 40, 50, 60],
* });
*
* const middleSection = series.between(1, 4);
* expect(middleSection.toArray()).to.eql([20, 30, 40, 50]);
* </pre>
*
* @example
* <pre>
*
* const timeSeries = ... a series indexed by date/time ...
*
* // Get all values between the start and end dates (inclusive).
* const result = timeSeries.after(new Date(2016, 5, 4), new Date(2016, 5, 22));
* </pre>
*/
between(startIndexValue: IndexT, endIndexValue: IndexT): ISeries<IndexT, ValueT>;
/**
* Format the series for display as a string.
* This forces lazy evaluation to complete.
*
* @return Generates and returns a string representation of the series.
*
* @example
* <pre>
*
* console.log(series.toString());
* </pre>
*/
toString(): string;
/**
* Parse a series with string values and convert it to a series with int values.
*
* @return Returns a new series with values parsed from strings to ints.
*
* @example
* <pre>
*
* const parsed = series.parseInts();
* </pre>
*/
parseInts(): ISeries<IndexT, number>;
/**
* Parse a series with string values and convert it to a series with float values.
*
* @return Returns a new series with values parsed from strings to floats.
*
* @example
* <pre>
*
* const parsed = series.parseFloats();
* </pre>
*/
parseFloats(): ISeries<IndexT, number>;
/**
* Parse a series with string values and convert it to a series with date values.
*
* @param formatString Optional formatting string for dates.
*
* Moment is used for date parsing.
* https://momentjs.com
*
* @return Returns a new series with values parsed from strings to dates.
*
* @example
* <pre>
*
* const parsed = series.parseDates();
* </pre>
*/
parseDates(formatString?: string): ISeries<IndexT, Date>;
/**
* Convert a series of values of different types to a series containing string values.
*
* @param formatString Optional formatting string for dates.
*
* Numeral.js is used for number formatting.
* http://numeraljs.com/
*
* Moment is used for date formatting.
* https://momentjs.com/docs/#/parsing/string-format/
*
* @return Returns a new series values converted from values to strings.
*
* @example
* <pre>
*
* const result = series.toStrings("YYYY-MM-DD");
* </pre>
*
* @example
* <pre>
*
* const result = series.toStrings("0.00");
* </pre>
*/
toStrings(formatString?: string): ISeries<IndexT, string>;
/**
* Forces lazy evaluation to complete and 'bakes' the series into memory.
*
* @return Returns a series that has been 'baked', all lazy evaluation has completed.
*
* @example
* <pre>
*
* const baked = series.bake();
* </pre>
*/
bake(): ISeries<IndexT, ValueT>;
/**
* Converts (inflates) a series to a {@link DataFrame}.
*
* @param selector Optional user-defined selector function that transforms each value to produce the dataframe.
*
* @returns Returns a dataframe that was created from the original series.
*
* @example
* <pre>
*
* const dataframe = series.inflate(); // Inflate a series of objects to a dataframe.
* </pre>
*
* @example
* <pre>
*
* const dataframe = series.inflate(value => { AColumn: value }); // Produces a dataframe with 1 column from a series of values.
* </pre>
*
* @example
* <pre>
*
* const dataframe = series.inflate(value => { AColumn: value.NestedValue }); // Extract a nested value and produce a dataframe from it.
* </pre>
*/
inflate<ToT = ValueT>(selector?: SelectorWithIndexFn<ValueT, ToT>): IDataFrame<IndexT, ToT>;
/**
* Sum the values in a series and returns the result.
*
* @returns Returns the sum of the number values in the series.
*
* @example
* <pre>
*
* const totalSales = salesFigures.sum();
* </pre>
*/
sum(): number;
/**
* Average the values in a series and returns the result.
*
* `average` is an alias of {@link Series.mean}.
*
* @returns Returns the average of the number values in the series.
*
* @example
* <pre>
*
* const averageSales = salesFigures.average();