UNPKG

data-forge

Version:

JavaScript data transformation and analysis toolkit inspired by Pandas and LINQ.

1,357 lines (1,355 loc) 171 kB
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();