// Generated by dts-bundle v0.7.3

export { Index, IIndex } from 'data-forge/--/build/lib/index';
export { Series, ISeries, SelectorWithIndexFn } from 'data-forge/--/build/lib/series';
export { DataFrame, IDataFrame } from 'data-forge/--/build/lib/dataframe';
import { Series, ISeries } from 'data-forge/--/build';
import { DataFrame, IDataFrame } from 'data-forge/--/build';
/**
    * Represents a field from a JavaScript object.
    */
export interface IFieldRecord {
        /**
            * The name of the field.
            */
        Field: string;
        /**
            * The value of the field.
            */
        Value: any;
}
/**
    * Convert a regular JavaScript obejct to a dataframe.
    * Each row in the dataframe represents a field from the object.
    *
    * @param obj - The JavaScript object to convert to a dataframe.
    *
    * @returns Returns a dataframe that lists the fields in the pass-in object.
    */
export declare function fromObject(obj: any): IDataFrame<number, IFieldRecord>;
/**
    * Deserialize a dataframe from a JSON text string.
    *
    * @param jsonTextString The JSON text to deserialize.
    *
    * @returns Returns a dataframe that has been deserialized from the JSON data.
    */
export declare function fromJSON(jsonTextString: string): IDataFrame<number, any>;
/**
    * Options for parsing CSV data.
    */
export interface ICSVOptions {
        /**
            * Optionally specifies the column names (when enabled, assumes that the header row is not read from the CSV data).
            * Default: undefined
            */
        columnNames?: Iterable<string>;
        /**
            * Automatically pick types based on what the value looks like.
            * Default: false.
            */
        dynamicTyping?: boolean;
        /**
            * Skip empty lines in the input.
            * Default: true
            */
        skipEmptyLines?: boolean;
}
/**
    * Deserialize a DataFrame from a CSV text string.
    *
    * @param csvTextString The CSV text to deserialize.
    * @param [config] Optional configuration options for parsing the CSV data.
    *
    * @returns Returns a dataframe that has been deserialized from the CSV data.
    */
export declare function fromCSV(csvTextString: string, config?: ICSVOptions): DataFrame<number, any>;
declare const concat: typeof Series.concat;
/**
    * Concatenate multiple series into a single series.
    * THIS FUNCTION IS DEPRECATED. Instead use dataFrame.Series.concat.
    *
    * @param {array} series - Array of series to concatenate.
    *
    * @returns {Series} - Returns the single concatendated series.
    */
export { concat as concatSeries };
declare const zip: typeof Series.zip;
/**
    * Zip together multiple series to create a new series.
    * THIS FUNCTION IS DEPRECATED. Instead use dataFrame.Series.zip.
    *
    * @param {array} series - Array of series to zip together.
    * @param {function} selector - Selector function that produces a new series based on the input series.
    *
    * @returns {Series} Returns a single series that is the combination of multiple input series that have been 'zipped' together by the 'selector' function.
    */
export { zip as zipSeries };
/**
    * Generate a series from a range of numbers.
    *
    * @param start - The value of the first number in the range.
    * @param count - The number of sequential values in the range.
    *
    * @returns Returns a series with a sequence of generated values. The series contains 'count' values beginning at 'start'.
    */
export declare function range(start: number, count: number): ISeries<number, number>;
/**
    * Replicate a particular value N times to create a series.
    *
    * @param value The value to replicate.
    * @param count The number of times to replicate the value.
    *
    * @returns Returns a new series that contains N copies of the value.
    */
export declare function replicate<ValueT>(value: ValueT, count: number): ISeries<number, ValueT>;
/**
    * Generate a data-frame containing a matrix of values.
    *
    * @param numColumns - The number of columns in the data-frame.
    * @param numRows - The number of rows in the data-frame.
    * @param start - The starting value.
    * @param increment - The value to increment by for each new value.
    *
    * @returns Returns a dataframe that contains a matrix of generated values.
    */
export declare function matrix(numColumns: number, numRows: number, start: number, increment: number): IDataFrame<number, any>;

import { ISeries, Series, SeriesConfigFn } from 'data-forge/--/build/lib/series';
/**
    * A predicate function for testing a value against another.
    */
export declare type PredicateFn = (value: any, against: any) => boolean;
/**
    * Interface that represents an index for a Series.
    */
export interface IIndex<IndexT> extends ISeries<number, IndexT> {
        /**
            * Get the type of the index.
            *
            * @returns Returns a string that specifies the type of the index.
            */
        getType(): string;
        /**
            * Get the less than operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getLessThan(): PredicateFn;
        /**
            * Get the less than or equal to operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getLessThanOrEqualTo(): PredicateFn;
        /**
            * Get the greater than operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getGreaterThan(): PredicateFn;
}
/**
    * Class that represents an index for a Series.
    */
export declare class Index<IndexT> extends Series<number, IndexT> implements IIndex<IndexT> {
        constructor(config?: any | SeriesConfigFn<number, IndexT>);
        /**
            * Get the type of the index.
            *
            * @returns Returns a string that specifies the type of the index.
            */
        getType(): string;
        /**
            * Get the less than operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getLessThan(): PredicateFn;
        /**
            * Get the less than or equal to operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getLessThanOrEqualTo(): PredicateFn;
        /**
            * Get the greater than operation for the index.
            *
            * @returns Returns a function that can be used to compare a value against an index value.
            */
        getGreaterThan(): PredicateFn;
}

import { IIndex } from 'data-forge/--/build/lib/index';
import { IDataFrame } from 'data-forge/--/build/lib/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?: Iterable<ValueT>;
        /***
            * The index for the serires.
            * If omitted the index will default to a 0-based index.
            */
        index?: 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?: 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.
    */
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;
}
/**
    * 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(): 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;
        /**
            * Generates a new series by repeatedly calling a user-defined selector function on each value in the original series.
            *
            * @param selector A user-defined selector function that transforms each row to create the new dataframe.
            *
            * @return Returns a new series with each value transformed by the selector function.
            *
            * @example
            * <pre>
            *
            * function transformValue (inputValue) {
            *      const outputValue = {
            *          // ... construct output value derived from input value ...
            *      };
            *
            *      return outputValue;
            * }
            *
            * const transformedSeries = series.select(value => transformValue(value));
            * </pre>
            */
        select<ToT>(selector: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
        /**
            * Generates a new series by repeatedly calling a user-defined selector function on each row in the original series.
            *
            * Similar to the {@link select} function, but in this case the selector function produces a collection of output values that are flattened and merged to create the new series.
            *
            * @param selector A user-defined selector function that transforms each value into a collection of output values.
            *
            * @return Returns a new series where each value has been transformed into 0 or more new values by the selector function.
            *
            * @example
            * <pre>
            *
            * function produceOutputValues (inputValue) {
            *      const outputValues = [];
            *      while (someCondition) {
            *          // ... generate zero or more output values ...
            *          outputValues.push(... some generated value ...);
            *      }
            *      return outputValues;
            * }
            *
            * const modifiedSeries = series.selectMany(value => produceOutputValues(value));
            * </pre>
            */
        selectMany<ToT>(selector: 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.
            *
            * @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): ISeries<number, 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.
            *
            * @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): ISeries<number, 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>;
        /**
            * Aggregate the values in the series to a single result.
            *
            * @param [seed] Optional seed value for producing the aggregation.
            * @param selector Function that takes the seed and then each value in the series and produces the aggregated value.
            *
            * @return Returns a new value that has been aggregated from the series using the 'selector' 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 totalSalesAllTime = 500; // We'll seed the aggregation with this value.
            * const dailySales = ... daily sales figures for the past month ...
            * const updatedTotalSalesAllTime = dailySales.aggregate(
            *      totalSalesAllTime,
            *      (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;
        /**
            * 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.
            *
            * @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): 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.
            *
            * @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): 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.
            *
            * @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): 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>;
        /**
            * 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.
            *
            * @param predicate Predicte function to filter values from the series. Returns true/truthy to keep values, or false/falsy to omit values.
            *
            * @return Returns a new series containing only the values from the original series that matched the predicate.
            *
            * @example
            * <pre>
            *
            * const filtered = series.where(salesFigure => salesFigure > 100); // Filter so we only have sales figures greater than 100.
            * </pre>
            */
        where(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
            *
            * @returns Returns the average of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const averageSales = salesFigures.average();
            * </pre>
            */
        average(): number;
        /**
            * Get the median value in the series.
            * Note that this sorts the series, which can be expensive.
            *
            * @returns Returns the median of the values in the series.
            *
            * @example
            * <pre>
            *
            * const medianSales = salesFigures.median();
            * </pre>
            */
        median(): number;
        /**
            * Get the min value in the series.
            *
            * @returns Returns the minimum of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const minSales = salesFigures.min();
            * </pre>
            */
        min(): number;
        /**
            * Get the max value in the series.
            *
            * @returns Returns the maximum of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const maxSales = salesFigures.max();
            * </pre>
            */
        max(): number;
        /**
            * Invert the sign of every number value in the series.
            * This assumes that the input series contains numbers.
            *
            * @returns Returns a new series with all number values inverted.
            *
            * @example
            * <pre>
            *
            * const inverted = series.invert();
            * </pre>
            */
        invert(): ISeries<IndexT, number>;
        /**
            * Counts the number of sequential values where the predicate evaluates to truthy.
            * Outputs 0 for values when the predicate evaluates to falsy.
            *
            * @param predicate User-defined function. Should evaluate to truthy to activate the counter or falsy to deactivate it.
            *
            * @returns Returns a new series that counts up the number of sequential values where the predicate evaluates to truthy. 0 values appear when the prediate evaluates to falsy.
            *
            * @example
            * <pre>
            *
            * const series = new Series([ 1, 10, 3, 15, 8, 5 ]);
            * const counted = series.counter(value => value >= 3);
            * console.log(counted.toString());
            * </pre>
            */
        counter(predicate: PredicateFn<ValueT>): ISeries<IndexT, number>;
        /**
            * Gets a new series in reverse order.
            *
            * @return Returns a new series that is the reverse of the original.
            *
            * @example
            * <pre>
            *
            * const reversed = series.reverse();
            * </pre>
            */
        reverse(): ISeries<IndexT, ValueT>;
        /**
            * Returns only the set of values in the series that are distinct.
            * Provide a user-defined selector to specify criteria for determining the distinctness.
            * This can be used to remove duplicate values from the series.
            *
            * @param [selector] Optional user-defined selector function that specifies the criteria used to make comparisons for duplicate values.
            *
            * @return Returns a series containing only unique values in the series.
            *
            * @example
            * <pre>
            *
            * const uniqueValues = series.distinct(); // Get only non-duplicated value in the series.
            * </pre>
            *
            * @example
            * <pre>
            *
            * const bucketedValues = series.distinct(value => Math.floor(value / 10)); // Lump values into buckets of 10.
            * </pre>
            */
        distinct<ToT>(selector?: SelectorFn<ValueT, ToT>): ISeries<IndexT, ValueT>;
        /**
            * Collects values in the series into a new series of groups according to a user-defined selector function.
            *
            * @param selector User-defined selector function that specifies the criteriay to group by.
            *
            * @return Returns a new series of groups. Each group is a series with values that have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const sales = ... product sales ...
            * const salesByProduct = sales.groupBy(sale => sale.ProductId);
            * for (const productSalesGroup of salesByProduct) {
            *      // ... do something with each product group ...
            *      const productId = productSalesGroup.first().ProductId;
            *      const totalSalesForProduct = productSalesGroup.deflate(sale => sale.Amount).sum();
            *      console.log(totalSalesForProduct);
            * }
            * </pre>
            */
        groupBy<GroupT>(selector: SelectorFn<ValueT, GroupT>): ISeries<number, ISeries<IndexT, ValueT>>;
        /**
            * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function.
            *
            * @param [selector] Optional selector that specifies the criteria for grouping.
            *
            * @return Returns a new series of groups. Each group is a series with values that are the same or have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Some ultra simple stock trading strategy backtesting...
            * const dailyStockPrice = ... daily stock price for a company ...
            * const priceGroups  = dailyStockPrice.groupBy(day => day.close > day.movingAverage);
            * for (const priceGroup of priceGroups) {
            *      // ... do something with each stock price group ...
            *
            *      const firstDay = priceGroup.first();
            *      if (firstDay.close > movingAverage) {
            *          // This group of days has the stock price above its moving average.
            *          // ... maybe enter a long trade here ...
            *      }
            *      else {
            *          // This group of days has the stock price below its moving average.
            *          // ... maybe enter a short trade here ...
            *      }
            * }
            * </pre>
            */
        groupSequentialBy<GroupT>(selector?: SelectorFn<ValueT, GroupT>): ISeries<number, ISeries<IndexT, ValueT>>;
        /**
            * Concatenate multiple other series onto this series.
            *
            * @param series Multiple arguments. Each can be either a series or an array of series.
            *
            * @return Returns a single series concatenated from multiple input series.
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, c);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat([b, c]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, [c, d]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const otherSeries = [... array of series...];
            * const concatenated = a.concat(otherSeries);
            * </pre>
            */
        concat(...series: (ISeries<IndexT, ValueT>[] | ISeries<IndexT, ValueT>)[]): ISeries<IndexT, ValueT>;
        /**
         * Zip together multiple series to create a new series.
         * Preserves the index of the first series.
         *
         * @param s2, s3, s4, s4 Multiple series to zip.
         * @param zipper User-defined zipper function that merges rows. It produces values for the new series based-on values from the input series.
         *
         * @return Returns a single series merged from multiple input series.
         *
         * @example
         * <pre>
         *
         * const a = new Series([1, 2, 3]);
         * const b = new Series([10, 20, 30]);
         * const zipped = a.zip(b (valueA, valueB) => valueA + valueB);
         * </pre>
         */
        zip<Index2T, Value2T, ResultT>(s2: ISeries<Index2T, Value2T>, zipper: Zip2Fn<ValueT, Value2T, ResultT>): ISeries<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, ResultT>(s2: ISeries<Index2T, Value2T>, s3: ISeries<Index3T, Value3T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): ISeries<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, Index4T, Value4T, ResultT>(s2: ISeries<Index2T, Value2T>, s3: ISeries<Index3T, Value3T>, s4: ISeries<Index4T, Value4T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): ISeries<IndexT, ResultT>;
        zip<ResultT>(...args: any[]): ISeries<IndexT, ResultT>;
        /**
            * Sorts the series in ascending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new series that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderBy(value => value);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderBy(value => value.NestedValue);
            * </pre>
            */
        orderBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
        /**
            * Sorts the series in descending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new series that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderByDescending(value => value);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderByDescending(value => value.NestedValue);
            * </pre>
            */
        orderByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
        /**
            * Creates a new series by merging two input dataframes.
            * The resulting series contains the union of value from the two input series.
            * These are the unique combination of values in both series.
            * This is basically a concatenation and then elimination of duplicates.
            *
            * @param other The other series to merge.
            * @param [selector] Optional user-defined selector function that selects the value to compare to determine distinctness.
            *
            * @return Returns the union of the two series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const merged = seriesA.union(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records that may contain the same
            * // customer record in each set. This is basically a concatenation
            * // of the series and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA.union(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            *
            *
            * @example
            * <pre>
            *
            * // Note that you can achieve the exact same result as the previous
            * // example by doing a {@link Series.concat) and {@link Series.distinct}
            * // of the input series and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA
            *      .concat(customerRecordsB)
            *      .distinct(customerRecord => customerRecord.CustomerId);
            * </pre>
            *
            */
        union<KeyT = ValueT>(other: ISeries<IndexT, ValueT>, selector?: SelectorFn<ValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains the intersection of values from the two input series.
            * These are only the values that appear in both series.
            *
            * @param inner The inner series to merge (the series you call the function on is the 'outer' series).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer series that is used to match the two series.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner series that is used to match the two series.
            *
            * @return Returns a new series that contains the intersection of values from the two input series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const mergedDf = seriesA.intersection(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records to find only the
            * // customers that appears in both.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const intersectionOfCustomerRecords = customerRecordsA.intersection(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        intersection<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only the values from the 1st series that don't appear in the 2nd series.
            * This is essentially subtracting the values from the 2nd series from the 1st and creating a new series with the remaining values.
            *
            * @param inner The inner series to merge (the series you call the function on is the 'outer' series).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer series that is used to match the two series.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner series that is used to match the two series.
            *
            * @return Returns a new series that contains only the values from the 1st series that don't appear in the 2nd series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const remainingDf = seriesA.except(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Find the list of customers haven't bought anything recently.
            * const allCustomers = ... list of all customers ...
            * const recentCustomers = ... list of customers who have purchased recently ...
            * const remainingCustomers = allCustomers.except(
            *      recentCustomers,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        except<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
             * Creates a new series by merging two input series.
             * The resulting dataframe contains only those value that have matching keys in both input series.
             *
             * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
             * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
             * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
             * @param resultSelector User-defined function that merges outer and inner values.
             *
             * @return Returns the new merged series.
             *
             * @example
             * <pre>
             *
             * // Join together two sets of customers to find those
             * // that have bought both product A and product B.
             * const customerWhoBoughtProductA = ...
             * const customerWhoBoughtProductB = ...
             * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
             *          customerWhoBoughtProductB,
             *          customerA => customerA.CustomerId, // Join key.
             *          customerB => customerB.CustomerId, // Join key.
             *          (customerA, customerB) => {
             *              return {
             *                  // ... merge the results ...
             *              };
             *          }
             *      );
             * </pre>
             */
        join<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT, InnerValueT, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are only present in or or the other of the series, not both.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either product A or product B, not not both.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const customersWhoBoughtEitherProductButNotBothDf = customerWhoBoughtProductA.joinOuter(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuter<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are present either in both series or only in the outer (left) series.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product A or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterLeft(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterLeft<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are present either in both series or only in the inner (right) series.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product B or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterRight(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterRight<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Produces a new series with all string values truncated to the requested maximum length.
            *
            * @param maxLength - The maximum length of the string values after truncation.
            *
            * @returns Returns a new series with strings that are truncated to the specified maximum length.
            *
            * @example
            * <pre>
            *
            * const truncated = series.truncateStrings(10); // Truncate all string values to max length of 10 characters.
            * </pre>
            */
        truncateStrings(maxLength: number): ISeries<IndexT, ValueT>;
        /**
            * Insert a pair at the start of the series.
            * Doesn't modify the original series! The returned series is entirely new and contains values from the original series plus the inserted pair.
            *
            * @param pair The index/value pair to insert.
            *
            * @return Returns a new series with the specified pair inserted.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to insert ...
            * const insertedSeries = series.insertPair([newIndex, newRows]);
            * </pre>
            */
        insertPair(pair: [IndexT, ValueT]): ISeries<IndexT, ValueT>;
        /**
            * Append a pair to the end of a series.
            * Doesn't modify the original series! The returned series is entirely new and contains values from the original series plus the appended pair.
            *
            * @param pair The index/value pair to append.
            *
            * @return Returns a new series with the specified pair appended.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to append ...
            * const appendedSeries = series.appendPair([newIndex, newRows]);
            * </pre>
            */
        appendPair(pair: [IndexT, ValueT]): ISeries<IndexT, ValueT>;
        /**
            * Fill gaps in a series.
            *
            * @param comparer User-defined comparer function that is passed pairA and pairB, two consecutive values, return truthy if there is a gap between the value, or falsey if there is no gap.
            * @param generator User-defined generator function that is passed pairA and pairB, two consecutive values, returns an array of pairs that fills the gap between the values.
            *
            * @return Returns a new series with gaps filled in.
            *
            * @example
            * <pre>
            *
            *   var sequenceWithGaps = ...
            *
            *  // Predicate that determines if there is a gap.
            *  var gapExists = (pairA, pairB) => {
            *      // Returns true if there is a gap.
            *      return true;
            *  };
            *
            *  // Generator function that produces new rows to fill the game.
            *  var gapFiller = (pairA, pairB) => {
            *      // Create an array of index, value pairs that fill the gaps between pairA and pairB.
            *      return [
            *          newPair1,
            *          newPair2,
            *          newPair3,
            *      ];
            *  };
            *
            *  var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller);
            * </pre>
            */
        fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries<IndexT, ValueT>;
        /**
            * Returns the specified default series if the input series is empty.
            *
            * @param defaultSequence Default series to return if the input series is empty.
            *
            * @return Returns 'defaultSequence' if the input series is empty.
            *
            * @example
            * <pre>
            *
            * const emptySeries = new Series();
            * const defaultSeries = new Series([ 1, 2, 3 ]);
            * expect(emptyDataFrame.defaultIfEmpty(defaultSeries)).to.eql(defaultSeries);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const nonEmptySeries = new Series([ 100 ]);
            * const defaultSeries = new Series([ 1, 2, 3 ]);
            * expect(nonEmptySeries.defaultIfEmpty(defaultSeries)).to.eql(nonEmptySeries);
            * </pre>
            */
        defaultIfEmpty(defaultSequence: ValueT[] | ISeries<IndexT, ValueT>): ISeries<IndexT, ValueT>;
        /**
            * Detect the the frequency of the types of the values in the series.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a {@link DataFrame} with rows that confirm to {@link ITypeFrequency} that describes the data types contained in the original series.
            *
            * @example
            * <pre>
            *
            * const dataTypes = series.detectTypes();
            * console.log(dataTypes.toString());
            * </pre>
            */
        detectTypes(): IDataFrame<number, ITypeFrequency>;
        /**
            * Detect the frequency of the values in the series.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a {@link DataFrame} with rows that conform to {@link IValueFrequency} that describes the values contained in the original series.
            *
            * @example
            * <pre>
            *
            * const dataValues = series.detectValues();
            * console.log(dataValues.toString());
            * </pre>
            */
        detectValues(): IDataFrame<number, IValueFrequency>;
        /**
            * Organise all values in the series into the specified number of buckets.
            * Assumes that the series is a series of numbers.
            *
            * @param numBuckets - The number of buckets to create.
            *
            * @returns Returns a dataframe containing bucketed values. The input values are divided up into these buckets.
            *
            * @example
            * <pre>
            *
            * const buckets = series.bucket(20); // Distribute values into 20 evenly spaced buckets.
            * console.log(buckets.toString());
            * </pre>
            */
        bucket(numBuckets: number): IDataFrame<IndexT, IBucket>;
}
/**
    * Interface to a series that has been ordered.
    */
export interface IOrderedSeries<IndexT = number, ValueT = any, SortT = any> extends ISeries<IndexT, ValueT> {
        /**
            * Applys additional sorting (ascending) to an already sorted series.
            *
            * @param selector User-defined selector that selects the additional value to sort by.
            *
            * @return Returns a new series has been additionally sorted by the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by salesperson and then by amount (from least to most).
            * const ordered = sales.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount);
            * </pre>
            */
        thenBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
        /**
            * Applys additional sorting (descending) to an already sorted series.
            *
            * @param selector User-defined selector that selects the additional value to sort by.
            *
            * @return Returns a new series has been additionally sorted by the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by salesperson and then by amount (from most to least).
            * const ordered = sales.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount);
            * </pre>
            */
        thenByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
}
/**
    * Class that represents a series containing a sequence of indexed values.
    */
export declare class Series<IndexT = number, ValueT = any> implements ISeries<IndexT, ValueT> {
        /**
            * Create a series.
            *
            * @param config This can be an array, a configuration object or a function that lazily produces a configuration object.
            *
            * It can be an array that specifies the values that the series contains.
            *
            * It can be a {@link ISeriesConfig} that defines the values and configuration of the series.
            *
            * Or it can be a function that lazily produces a {@link ISeriesConfig}.
            *
            * @example
            * <pre>
            *
            * const series = new Series();
            * </pre>
            *
            * @example
            * <pre>
            *
            * const series = new Series([10, 20, 30, 40]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const series = new Series({ index: [1, 2, 3, 4], values: [10, 20, 30, 40]});
            * </pre>
            *
            * @example
            * <pre>
            *
            * const lazyInit = () => ({ index: [1, 2, 3, 4], values: [10, 20, 30, 40] });
            * const series = new Series(lazyInit);
            * </pre>
            */
        constructor(config?: Iterable<ValueT> | ISeriesConfig<IndexT, ValueT> | SeriesConfigFn<IndexT, 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 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 multiple series into a single series.
            * Values are merged by index.
            * Values at each index are combined into arrays in the resulting series.
            *
            * @param series An array or series of series to merge.
            *
            * @returns The merged series.
            *
            * @example
            * <pre>
            *
            * const mergedSeries = Series.merge([series1, series2, etc]);
            * </pre>
            */
        static merge<MergedValueT = any, IndexT = any>(series: Iterable<ISeries<IndexT, any>>): ISeries<IndexT, MergedValueT[]>;
        /**
             * 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(): any[];
        /**
            * 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;
        /**
            * Generates a new series by repeatedly calling a user-defined selector function on each value in the original series.
            *
            * @param selector A user-defined selector function that transforms each row to create the new dataframe.
            *
            * @return Returns a new series with each value transformed by the selector function.
            *
            * @example
            * <pre>
            *
            * function transformValue (inputValue) {
            *      const outputValue = {
            *          // ... construct output value derived from input value ...
            *      };
            *
            *      return outputValue;
            * }
            *
            * const transformedSeries = series.select(value => transformValue(value));
            * </pre>
            */
        select<ToT>(selector: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
        /**
            * Generates a new series by repeatedly calling a user-defined selector function on each row in the original series.
            *
            * Similar to the {@link select} function, but in this case the selector function produces a collection of output values that are flattened and merged to create the new series.
            *
            * @param selector A user-defined selector function that transforms each value into a collection of output values.
            *
            * @return Returns a new series where each value has been transformed into 0 or more new values by the selector function.
            *
            * @example
            * <pre>
            *
            * function produceOutputValues (inputValue) {
            *      const outputValues = [];
            *      while (someCondition) {
            *          // ... generate zero or more output values ...
            *          outputValues.push(... some generated value ...);
            *      }
            *      return outputValues;
            * }
            *
            * const modifiedSeries = series.selectMany(value => produceOutputValues(value));
            * </pre>
            */
        selectMany<ToT>(selector: 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.
            *
            * @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): ISeries<number, 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.
            *
            * @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): ISeries<number, 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 = ValueT>(selector?: SelectorFn<ValueT, ToT>): ISeries<IndexT, ValueT>;
        /**
            * Aggregate the values in the series to a single result.
            *
            * @param [seed] Optional seed value for producing the aggregation.
            * @param selector Function that takes the seed and then each value in the series and produces the aggregated value.
            *
            * @return Returns a new value that has been aggregated from the series using the 'selector' 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 totalSalesAllTime = 500; // We'll seed the aggregation with this value.
            * const dailySales = ... daily sales figures for the past month ...
            * const updatedTotalSalesAllTime = dailySales.aggregate(
            *      totalSalesAllTime,
            *      (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;
        /**
            * 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.
            *
            * @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): 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.
            *
            * @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): 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.
            *
            * @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): 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>;
        /**
            * 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>;
        /**
            * Static version of the count function for use with summarize and pivot functions.
            *
            * @param series Input series to be counted.
            *
            * @returns Returns the count of values in the series.
            *
            * @example
            * <pre>
            *
            * const summary = dataFrame.summarize({
            *      ColumnToBeCounted: Series.count,
            * });
            * </pre>
            */
        static count<IndexT = any>(series: ISeries<IndexT, number>): number;
        /**
            * 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.
            *
            * @param predicate Predicte function to filter values from the series. Returns true/truthy to keep values, or false/falsy to omit values.
            *
            * @return Returns a new series containing only the values from the original series that matched the predicate.
            *
            * @example
            * <pre>
            *
            * const filtered = series.where(salesFigure => salesFigure > 100); // Filter so we only have sales figures greater than 100.
            * </pre>
            */
        where(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;
        static parseInt(value: any | undefined, valueIndex: number): number | undefined;
        /**
            * 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>;
        static parseFloat(value: any | undefined, valueIndex: number): number | undefined;
        /**
            * 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>;
        static parseDate(value: any | undefined, valueIndex: number, formatString?: string): Date | undefined;
        /**
            * 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>;
        static toString(value: any | undefined, formatString?: string): string | undefined | null;
        /**
            * 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>;
        /**
            * Static version of the sum function for use with summarize and pivot functions.
            *
            * @param series Input series to be summed.
            *
            * @returns Returns the sum of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const summary = dataFrame.summarize({
            *      ColumnToBeSummed: Series.sum,
            * });
            * </pre>
            */
        static sum<IndexT = any>(series: ISeries<IndexT, number>): number;
        /**
            * 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;
        /**
            * Static version of the average function for use with summarize and pivot functions.
            *
            * @param series Input series to be averaged.
            *
            * @returns Returns the average of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const summary = dataFrame.summarize({
            *      ColumnToBeAveraged: Series.average,
            * });
            * </pre>
            */
        static average<IndexT = any>(series: ISeries<IndexT, number>): number;
        /**
            * Average the values in a series and returns the result
            *
            * @returns Returns the average of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const averageSales = salesFigures.average();
            * </pre>
            */
        average(): number;
        /**
            * Get the median value in the series.
            * Note that this sorts the series, which can be expensive.
            *
            * @returns Returns the median of the values in the series.
            *
            * @example
            * <pre>
            *
            * const medianSales = salesFigures.median();
            * </pre>
            */
        median(): number;
        /**
            * Static version of the min function for use with summarize and pivot functions.
            *
            * @param series Input series to find the minimum of.
            *
            * @returns Returns the minimum of number values in the series.
            *
            * @example
            * <pre>
            *
            * const summary = dataFrame.summarize({
            *      Column: Series.min,
            * });
            * </pre>
            */
        static min<IndexT = any>(series: ISeries<IndexT, number>): number;
        /**
            * Get the min value in the series.
            *
            * @returns Returns the minimum of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const minSales = salesFigures.min();
            * </pre>
            */
        min(): number;
        /**
            * Static version of the max function for use with summarize and pivot functions.
            *
            * @param series Input series to find the maximum of.
            *
            * @returns Returns the maximum of number values in the series.
            *
            * @example
            * <pre>
            *
            * const summary = dataFrame.summarize({
            *      Column: Series.max,
            * });
            * </pre>
            */
        static max<IndexT = any>(series: ISeries<IndexT, number>): number;
        /**
            * Get the max value in the series.
            *
            * @returns Returns the maximum of the number values in the series.
            *
            * @example
            * <pre>
            *
            * const maxSales = salesFigures.max();
            * </pre>
            */
        max(): number;
        /**
            * Invert the sign of every number value in the series.
            * This assumes that the input series contains numbers.
            *
            * @returns Returns a new series with all number values inverted.
            *
            * @example
            * <pre>
            *
            * const inverted = series.invert();
            * </pre>
            */
        invert(): ISeries<IndexT, number>;
        /**
            * Counts the number of sequential values where the predicate evaluates to truthy.
            * Outputs 0 for values when the predicate evaluates to falsy.
            *
            * @param predicate User-defined function. Should evaluate to truthy to activate the counter or falsy to deactivate it.
            *
            * @returns Returns a new series that counts up the number of sequential values where the predicate evaluates to truthy. 0 values appear when the prediate evaluates to falsy.
            *
            * @example
            * <pre>
            *
            * const series = new Series([ 1, 10, 3, 15, 8, 5 ]);
            * const counted = series.counter(value => value >= 3);
            * console.log(counted.toString());
            * </pre>
            */
        counter(predicate: PredicateFn<ValueT>): ISeries<IndexT, number>;
        /**
            * Gets a new series in reverse order.
            *
            * @return Returns a new series that is the reverse of the original.
            *
            * @example
            * <pre>
            *
            * const reversed = series.reverse();
            * </pre>
            */
        reverse(): ISeries<IndexT, ValueT>;
        /**
            * Returns only the set of values in the series that are distinct.
            * Provide a user-defined selector to specify criteria for determining the distinctness.
            * This can be used to remove duplicate values from the series.
            *
            * @param [selector] Optional user-defined selector function that specifies the criteria used to make comparisons for duplicate values.
            *
            * @return Returns a series containing only unique values in the series.
            *
            * @example
            * <pre>
            *
            * const uniqueValues = series.distinct(); // Get only non-duplicated value in the series.
            * </pre>
            *
            * @example
            * <pre>
            *
            * const bucketedValues = series.distinct(value => Math.floor(value / 10)); // Lump values into buckets of 10.
            * </pre>
            */
        distinct<ToT>(selector?: SelectorFn<ValueT, ToT>): ISeries<IndexT, ValueT>;
        /**
            * Collects values in the series into a new series of groups according to a user-defined selector function.
            *
            * @param selector User-defined selector function that specifies the criteriay to group by.
            *
            * @return Returns a new series of groups. Each group is a series with values that have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const sales = ... product sales ...
            * const salesByProduct = sales.groupBy(sale => sale.ProductId);
            * for (const productSalesGroup of salesByProduct) {
            *      // ... do something with each product group ...
            *      const productId = productSalesGroup.first().ProductId;
            *      const totalSalesForProduct = productSalesGroup.deflate(sale => sale.Amount).sum();
            *      console.log(totalSalesForProduct);
            * }
            * </pre>
            */
        groupBy<GroupT>(selector: SelectorWithIndexFn<ValueT, GroupT>): ISeries<number, ISeries<IndexT, ValueT>>;
        /**
            * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function.
            *
            * @param [selector] Optional selector that specifies the criteria for grouping.
            *
            * @return Returns a new series of groups. Each group is a series with values that are the same or have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Some ultra simple stock trading strategy backtesting...
            * const dailyStockPrice = ... daily stock price for a company ...
            * const priceGroups  = dailyStockPrice.groupBy(day => day.close > day.movingAverage);
            * for (const priceGroup of priceGroups) {
            *      // ... do something with each stock price group ...
            *
            *      const firstDay = priceGroup.first();
            *      if (firstDay.close > movingAverage) {
            *          // This group of days has the stock price above its moving average.
            *          // ... maybe enter a long trade here ...
            *      }
            *      else {
            *          // This group of days has the stock price below its moving average.
            *          // ... maybe enter a short trade here ...
            *      }
            * }
            * </pre>
            */
        groupSequentialBy<GroupT>(selector?: SelectorFn<ValueT, GroupT>): ISeries<number, ISeries<IndexT, ValueT>>;
        /**
            * Concatenate multiple series into a single series.
            *
            * @param series - Array of series to concatenate.
            *
            * @returns Returns a single series concatenated from multiple input series.
            */
        static concat<IndexT = any, ValueT = any>(series: ISeries<IndexT, ValueT>[]): ISeries<IndexT, ValueT>;
        /**
            * Concatenate multiple other series onto this series.
            *
            * @param series Multiple arguments. Each can be either a series or an array of series.
            *
            * @return Returns a single series concatenated from multiple input series.
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, c);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat([b, c]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, [c, d]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const otherSeries = [... array of series...];
            * const concatenated = a.concat(otherSeries);
            * </pre>
            */
        concat(...series: (ISeries<IndexT, ValueT>[] | ISeries<IndexT, ValueT>)[]): ISeries<IndexT, ValueT>;
        /**
         * Zip together multiple series to create a new series.
         * Preserves the index of the first series.
         *
         * @param series - An iterable of series to be zipped.
         * @param zipper - Selector function that produces a new series based on the input series.
         *
         * @returns Returns a single series zipped from multiple input series.
         */
        static zip<IndexT = any, ValueT = any, ResultT = any>(series: Iterable<ISeries<IndexT, ValueT>>, zipper: ZipNFn<ValueT, ResultT>): ISeries<IndexT, ResultT>;
        /**
         * Merge together multiple series to create a new series.
         * Preserves the index of the first series.
         *
         * @param s2, s3, s4, s4 Multiple series to zip.
         * @param zipper User-defined zipper function that merges rows. It produces values for the new series based-on values from the input series.
         *
         * @return Returns a single series merged from multiple input series.
         *
         * @example
         * <pre>
         *
         * const a = new Series([1, 2, 3]);
         * const b = new Series([10, 20, 30]);
         * const zipped = a.zip(b (valueA, valueB) => valueA + valueB);
         * </pre>
         */
        zip<Index2T, Value2T, ResultT>(s2: ISeries<Index2T, Value2T>, zipper: Zip2Fn<ValueT, Value2T, ResultT>): ISeries<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, ResultT>(s2: ISeries<Index2T, Value2T>, s3: ISeries<Index3T, Value3T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): ISeries<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, Index4T, Value4T, ResultT>(s2: ISeries<Index2T, Value2T>, s3: ISeries<Index3T, Value3T>, s4: ISeries<Index4T, Value4T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): ISeries<IndexT, ResultT>;
        /**
            * Sorts the series in ascending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new series that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderBy(value => value);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderBy(value => value.NestedValue);
            * </pre>
            */
        orderBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
        /**
            * Sorts the series in descending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new series that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderByDescending(value => value);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const orderedSeries = series.orderByDescending(value => value.NestedValue);
            * </pre>
            */
        orderByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedSeries<IndexT, ValueT, SortT>;
        /**
            * Creates a new series by merging two input dataframes.
            * The resulting series contains the union of value from the two input series.
            * These are the unique combination of values in both series.
            * This is basically a concatenation and then elimination of duplicates.
            *
            * @param other The other series to merge.
            * @param [selector] Optional user-defined selector function that selects the value to compare to determine distinctness.
            *
            * @return Returns the union of the two series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const merged = seriesA.union(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records that may contain the same
            * // customer record in each set. This is basically a concatenation
            * // of the series and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA.union(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            *
            *
            * @example
            * <pre>
            *
            * // Note that you can achieve the exact same result as the previous
            * // example by doing a {@link Series.concat) and {@link Series.distinct}
            * // of the input series and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA
            *      .concat(customerRecordsB)
            *      .distinct(customerRecord => customerRecord.CustomerId);
            * </pre>
            *
            */
        union<KeyT = ValueT>(other: ISeries<IndexT, ValueT>, selector?: SelectorFn<ValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains the intersection of values from the two input series.
            * These are only the values that appear in both series.
            *
            * @param inner The inner series to merge (the series you call the function on is the 'outer' series).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer series that is used to match the two series.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner series that is used to match the two series.
            *
            * @return Returns a new series that contains the intersection of values from the two input series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const mergedDf = seriesA.intersection(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records to find only the
            * // customers that appears in both.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const intersectionOfCustomerRecords = customerRecordsA.intersection(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        intersection<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only the values from the 1st series that don't appear in the 2nd series.
            * This is essentially subtracting the values from the 2nd series from the 1st and creating a new series with the remaining values.
            *
            * @param inner The inner series to merge (the series you call the function on is the 'outer' series).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer series that is used to match the two series.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner series that is used to match the two series.
            *
            * @return Returns a new series that contains only the values from the 1st series that don't appear in the 2nd series.
            *
            * @example
            * <pre>
            *
            * const seriesA = ...
            * const seriesB = ...
            * const remainingDf = seriesA.except(seriesB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Find the list of customers haven't bought anything recently.
            * const allCustomers = ... list of all customers ...
            * const recentCustomers = ... list of customers who have purchased recently ...
            * const remainingCustomers = allCustomers.except(
            *      recentCustomers,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        except<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): ISeries<IndexT, ValueT>;
        /**
             * Creates a new series by merging two input series.
             * The resulting dataframe contains only those value that have matching keys in both input series.
             *
             * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
             * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
             * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
             * @param resultSelector User-defined function that merges outer and inner values.
             *
             * @return Returns the new merged series.
             *
             * @example
             * <pre>
             *
             * // Join together two sets of customers to find those
             * // that have bought both product A and product B.
             * const customerWhoBoughtProductA = ...
             * const customerWhoBoughtProductB = ...
             * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
             *          customerWhoBoughtProductB,
             *          customerA => customerA.CustomerId, // Join key.
             *          customerB => customerB.CustomerId, // Join key.
             *          (customerA, customerB) => {
             *              return {
             *                  // ... merge the results ...
             *              };
             *          }
             *      );
             * </pre>
             */
        join<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT, InnerValueT, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are only present in or or the other of the series, not both.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either product A or product B, not not both.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const customersWhoBoughtEitherProductButNotBothDf = customerWhoBoughtProductA.joinOuter(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuter<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are present either in both series or only in the outer (left) series.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product A or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterLeft(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterLeft<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Creates a new series by merging two input series.
            * The resulting series contains only those values that are present either in both series or only in the inner (right) series.
            *
            * @param inner The 'inner' series to join (the series you are callling the function on is the 'outer' series).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer series.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner series.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged series.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product B or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterRight(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterRight<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: ISeries<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): ISeries<number, ResultValueT>;
        /**
            * Produces a new series with all string values truncated to the requested maximum length.
            *
            * @param maxLength - The maximum length of the string values after truncation.
            *
            * @returns Returns a new series with strings that are truncated to the specified maximum length.
            *
            * @example
            * <pre>
            *
            * const truncated = series.truncateStrings(10); // Truncate all string values to max length of 10 characters.
            * </pre>
            */
        truncateStrings(maxLength: number): ISeries<IndexT, ValueT>;
        /**
            * Insert a pair at the start of the series.
            * Doesn't modify the original series! The returned series is entirely new and contains values from the original series plus the inserted pair.
            *
            * @param pair The index/value pair to insert.
            *
            * @return Returns a new series with the specified pair inserted.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to insert ...
            * const insertedSeries = series.insertPair([newIndex, newRows]);
            * </pre>
            */
        insertPair(pair: [IndexT, ValueT]): ISeries<IndexT, ValueT>;
        /**
            * Append a pair to the end of a series.
            * Doesn't modify the original series! The returned series is entirely new and contains values from the original series plus the appended pair.
            *
            * @param pair The index/value pair to append.
            *
            * @return Returns a new series with the specified pair appended.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to append ...
            * const appendedSeries = series.appendPair([newIndex, newRows]);
            * </pre>
            */
        appendPair(pair: [IndexT, ValueT]): ISeries<IndexT, ValueT>;
        /**
            * Fill gaps in a series.
            *
            * @param comparer User-defined comparer function that is passed pairA and pairB, two consecutive values, return truthy if there is a gap between the value, or falsey if there is no gap.
            * @param generator User-defined generator function that is passed pairA and pairB, two consecutive values, returns an array of pairs that fills the gap between the values.
            *
            * @return Returns a new series with gaps filled in.
            *
            * @example
            * <pre>
            *
            *   var sequenceWithGaps = ...
            *
            *  // Predicate that determines if there is a gap.
            *  var gapExists = (pairA, pairB) => {
            *      // Returns true if there is a gap.
            *      return true;
            *  };
            *
            *  // Generator function that produces new rows to fill the game.
            *  var gapFiller = (pairA, pairB) => {
            *      // Create an array of index, value pairs that fill the gaps between pairA and pairB.
            *      return [
            *          newPair1,
            *          newPair2,
            *          newPair3,
            *      ];
            *  };
            *
            *  var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller);
            * </pre>
            */
        fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): ISeries<IndexT, ValueT>;
        /**
            * Returns the specified default series if the input series is empty.
            *
            * @param defaultSequence Default series to return if the input series is empty.
            *
            * @return Returns 'defaultSequence' if the input series is empty.
            *
            * @example
            * <pre>
            *
            * const emptySeries = new Series();
            * const defaultSeries = new Series([ 1, 2, 3 ]);
            * expect(emptyDataFrame.defaultIfEmpty(defaultSeries)).to.eql(defaultSeries);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const nonEmptySeries = new Series([ 100 ]);
            * const defaultSeries = new Series([ 1, 2, 3 ]);
            * expect(nonEmptySeries.defaultIfEmpty(defaultSeries)).to.eql(nonEmptySeries);
            * </pre>
            */
        defaultIfEmpty(defaultSequence: ValueT[] | ISeries<IndexT, ValueT>): ISeries<IndexT, ValueT>;
        /**
            * Detect the the frequency of the types of the values in the series.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a {@link DataFrame} with rows that confirm to {@link ITypeFrequency} that describes the data types contained in the original series.
            *
            * @example
            * <pre>
            *
            * const dataTypes = series.detectTypes();
            * console.log(dataTypes.toString());
            * </pre>
            */
        detectTypes(): IDataFrame<number, ITypeFrequency>;
        /**
            * Detect the frequency of the values in the series.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a {@link DataFrame} with rows that conform to {@link IValueFrequency} that describes the values contained in the original series.
            *
            * @example
            * <pre>
            *
            * const dataValues = series.detectValues();
            * console.log(dataValues.toString());
            * </pre>
            */
        detectValues(): IDataFrame<number, IValueFrequency>;
        /**
            * Organise all values in the series into the specified number of buckets.
            * Assumes that the series is a series of numbers.
            *
            * @param numBuckets - The number of buckets to create.
            *
            * @returns Returns a dataframe containing bucketed values. The input values are divided up into these buckets.
            *
            * @example
            * <pre>
            *
            * const buckets = series.bucket(20); // Distribute values into 20 evenly spaced buckets.
            * console.log(buckets.toString());
            * </pre>
            */
        bucket(numBuckets: number): IDataFrame<IndexT, IBucket>;
        /***
            * Allows the series to be queried to confirm that it is actually a series.
            * Used from JavaScript to tell the difference between a Series and a DataFrame.
            *
            * @return Returns the string "series".
            */
        getTypeCode(): string;
}

import { IIndex } from 'data-forge/--/build/lib/index';
import { ISeries, SelectorWithIndexFn, PredicateFn, ComparerFn, SelectorFn, AggregateFn, Zip2Fn, Zip3Fn, ZipNFn, CallbackFn, JoinFn, GapFillFn } from 'data-forge/--/build/lib/series';
/**
    * An object whose fields specify the data for named columns.
    */
export interface IColumnSpec {
        [index: string]: Iterable<any> | ISeries<any, any>;
}
/**
    * Specifes the format per column when converting columns to strings.
    */
export interface IFormatSpec {
        [index: string]: string;
}
/**
    * An function that aggregates a series.
    */
export declare type SeriesAggregatorFn<IndexT, ValueT, OutputT> = (values: ISeries<IndexT, ValueT>) => OutputT;
/**
    * Specification that can produce multiple output columns from a single input column of a dataframe.
    */
export interface IColumnAggregatorSpec {
        [outputColumnName: string]: SeriesAggregatorFn<any, any, any>;
}
/**
    * Specification that can aggregate multiple input columns in a dataframe to produce multiple output columns.
    */
export interface IMultiColumnAggregatorSpec {
        [inputColumnName: string]: SeriesAggregatorFn<any, any, any> | IColumnAggregatorSpec;
}
/**
    * Defines the configuration for a new column.
    */
export interface IColumnConfig {
        /**
            * The name of the new column.
            */
        name: string;
        /**
            * The series of values for the column.
            */
        series: Iterable<any> | ISeries<any, any>;
}
/**
    * Options for CSV output.
    */
export interface ICSVOutputOptions {
        /**
            * Enable or disable output of the CSV header line.
            * Defaults to true.
            */
        header?: boolean;
}
/**
    * Used to configure a dataframe.
    */
export interface IDataFrameConfig<IndexT, ValueT> {
        /**
            * Values to put in the dataframe.
            * This should be array or iterable of JavaScript objects.
            * Each element in the array contains fields that match the columns of the dataframe.
            */
        values?: Iterable<ValueT>;
        /**
            * CSV style rows to put in the dataframe.
            * An array of arrays. Each element in the top level array is a row of data.
            * Each row of data contains field values in column order.
            */
        rows?: Iterable<any[]>;
        /***
            * The index for the dataframe.
            * If omitted the index will default to a 0-based index.
            */
        index?: Iterable<IndexT>;
        /**
            * Array or iterable of index,value pairs to put in the dataframe.
            * If index and values are not separately specified they can be extracted
            * from the pairs.
            */
        pairs?: Iterable<[IndexT, ValueT]>;
        /**
            * Array or iterable of column names that are in the dataframe.
            * The order matters. This arrays specifies the ordering of columns which
            * is important when rendering tables or writing out CSV data files.
            * If this is omitted column names will automatically be determined
            * from the fields of the first row/value in the dataframe.
            */
        columnNames?: Iterable<string>;
        /***
            * Set to true when the dataframe has been baked into memory
            * and does not need to be lazily evaluated.
            */
        baked?: boolean;
        /**
            * Set to true to consider all rows/values in the dataframe when
            * determining the column names. Otherwise only the first row is considered.
            * You should use this if you have ireggular fields in the objects that
            * make up the rows/values of the dataframe.
            */
        considerAllRows?: boolean;
        /**
            * Explicitly specify data for named columns to put in the dataframe.
            */
        columns?: Iterable<IColumnConfig> | IColumnSpec;
}
/**
    * Represents a named column in a dataframe.
    */
export interface IColumn {
        /**
            * The name of the column.
            */
        name: string;
        /**
            * The data type of the column.
            */
        type: string;
        /**
            * The data series from the column.
            */
        series: ISeries<any, any>;
}
/**
    * An object whose fields specify data for named named columns or user-defined generator functions that generate the data for the columns.
    */
export interface IColumnGenSpec {
        [index: string]: ISeries<any, any> | SeriesSelectorFn<any, any, any>;
}
/**
    * A string-to-string mapping that specifies how to rename columns.
    */
export interface IColumnRenameSpec {
        [index: string]: string;
}
/**
    * Specifies columns to transform and the user-defined selector function that does the transformation.
    */
export interface IColumnTransformSpec {
        [columnName: string]: SelectorWithIndexFn<any, any>;
}
/**
    * Specifies columns that should be aggregated and a user-defined aggregator function to do the aggregation.
    */
export interface IColumnAggregateSpec {
        [index: string]: AggregateFn<any, any>;
}
/**
    * A selector function that can select a series from a dataframe.
    */
export declare type SeriesSelectorFn<IndexT, DataFrameValueT, SeriesValueT> = (dataFrame: IDataFrame<IndexT, DataFrameValueT>) => ISeries<IndexT, SeriesValueT>;
export declare type DataFrameConfigFn<IndexT, ValueT> = () => IDataFrameConfig<IndexT, ValueT>;
/**
    * Represents the frequency of a type in a series or dataframe.
    */
export interface ITypeFrequency {
        /**
            * Name of the column containing the value.
            */
        Column: string;
        /**
            * 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 {
        /**
            * Name of the column containing the value.
            */
        Column: string;
        /**
            * The value.
            */
        Value: any;
        /**
            * The frequency of the value's appearance in the series or dataframe.
            */
        Frequency: number;
}
/**
    * Records column types in a serialized dataframe.
    * This is mainly used to reinstantiate dates that have been passed
    * across the wire, because these are the only values that aren't already
    * preserved by the JSON data format.
    */
export interface IColumnTypes {
        [index: string]: string;
}
/**
    * The serialized index for a dataframe.
    */
export interface ISerializedIndex {
        /**
            * The data type of the index.
            */
        type: string;
        /**
            * Values in the index.
            */
        values: any[];
}
/**
    * The serialized form of a DataFrame.
    * This is an ordinary JavaScript data structure that can be used to transfer a dataframe across the wire and
    * reinstantiate it on the otherside (this is necessary to maintain a stable column ordering and to allow date values to be reinstantiated).
    */
export interface ISerializedDataFrame {
        /**
            * The order of columns in the dataframe.
            */
        columnOrder: string[];
        /**
            * Records the columns and their types.
            */
        columns: IColumnTypes;
        /**
            * The serialized index for the dataframe.
            */
        index: ISerializedIndex;
        /**
            * Rows/values contained in the dataframe..
            */
        values: any[];
}
/**
    * Interface that represents a dataframe.
    * A dataframe contains an indexed sequence of data records.
    * Think of it as a spreadsheet or CSV file in memory.
    *
    * Each data record contains multiple named fields, the value of each field represents one row in a column of data.
    * Each column of data is a named {@link Series}.
    * You think of a dataframe a collection of named data series.
    *
    * @typeparam IndexT The type to use for the index.
    * @typeparam ValueT The type to use for each row/data record.
    */
export interface IDataFrame<IndexT = number, ValueT = any> extends Iterable<ValueT> {
        /**
            * Get an iterator to enumerate the rows of the dataframe.
            * Enumerating the iterator forces lazy evaluation to complete.
            * This function is automatically called by `for...of`.
            *
            * @return An iterator for the rows in the dataframe.
            *
            * @example
            * <pre>
            *
            * for (const row of df) {
            *     // ... do something with the row ...
            * }
            * </pre>
            */
        [Symbol.iterator](): Iterator<ValueT>;
        /**
            * Get the names of the columns in the dataframe.
            *
            * @return Returns an array of the column names in the dataframe.
            *
            * @example
            * <pre>
            *
            * console.log(df.getColumnNames());
            * </pre>
            */
        getColumnNames(): string[];
        /**
            * Retreive the collection of all columns in the dataframe.
            *
            * @return Returns a {@link Series} containing the names of the columns in the dataframe.
            *
            * @example
            * <pre>
            *
            * for (const column in df.getColummns()) {
            *      console.log("Column name: ");
            *      console.log(column.name);
            *
            *      console.log("Data:");
            *      console.log(column.series.toArray());
            * }
            * </pre>
            */
        getColumns(): ISeries<number, IColumn>;
        /**
            * Cast the value of the dataframe to a new type.
            * This operation has no effect but to retype the r9ws that the dataframe contains.
            *
            * @return The same dataframe, but with the type changed.
            *
            * @example
            * <pre>
            *
            * const castDf = df.cast<SomeOtherType>();
            * </pre>
            */
        cast<NewValueT>(): IDataFrame<IndexT, NewValueT>;
        /**
            * Get the index for the dataframe.
            *
            * @return The {@link Index} for the dataframe.
            *
            * @example
            * <pre>
            *
            * const index = df.getIndex();
            * </pre>
            */
        getIndex(): IIndex<IndexT>;
        /**
            * Set a named column as the {@link Index} of the dataframe.
            *
            * @param columnName Name of the column to use as the new {@link Index} of the returned dataframe.
            *
            * @return Returns a new dataframe with the values of the specified column as the new {@link Index}.
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.setIndex("SomeColumn");
            * </pre>
            */
        setIndex<NewIndexT = any>(columnName: string): IDataFrame<NewIndexT, ValueT>;
        /**
            * Apply a new {@link Index} to the dataframe.
            *
            * @param newIndex The new array or iterable to be the new {@link Index} of the dataframe. Can also be a selector to choose the {@link Index} for each row in the dataframe.
            *
            * @return Returns a new dataframe with the specified {@link Index} attached.
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex([10, 20, 30]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(df.getSeries("SomeColumn"));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(row => row.SomeColumn);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(row => row.SomeColumn + 20);
            * </pre>
            */
        withIndex<NewIndexT>(newIndex: Iterable<NewIndexT> | SelectorFn<ValueT, NewIndexT>): IDataFrame<NewIndexT, ValueT>;
        /**
            * Resets the {@link Index} of the dataframe back to the default zero-based sequential integer index.
            *
            * @return Returns a new dataframe with the {@link Index} reset to the default zero-based index.
            *
            * @example
            * <pre>
            *
            * const dfWithResetIndex = df.resetIndex();
            * </pre>
            */
        resetIndex(): IDataFrame<number, ValueT>;
        /**
            * Extract a {@link Series} from a named column in the dataframe.
            *
            * @param columnName Specifies the name of the column that contains the {@link Series} to retreive.
            *
            * @return Returns the {@link Series} extracted from the named column in the dataframe.
            *
            * @example
            * <pre>
            *
            * const series = df.getSeries("SomeColumn");
            * </pre>
            */
        getSeries<SeriesValueT = any>(columnName: string): ISeries<IndexT, SeriesValueT>;
        /**
            * Determine if the dataframe contains a {@link Series} the specified named column.
            *
            * @param columnName Name of the column to check for.
            *
            * @return Returns true if the dataframe contains the requested {@link Series}, otherwise returns false.
            *
            * @example
            * <pre>
            *
            * if (df.hasSeries("SomeColumn")) {
            *      // ... the dataframe contains a series with the specified column name ...
            * }
            * </pre>
            */
        hasSeries(columnName: string): boolean;
        /**
            * Verify the existence of a name column and extracts the {@link Series} for it.
            * Throws an exception if the requested column doesn't exist.
            *
            * @param columnName Name of the column to extract.
            *
            * @return Returns the {@link Series} for the column if it exists, otherwise it throws an exception.
            *
            * @example
            * <pre>
            *
            * try {
            *      const series = df.expectSeries("SomeColumn");
            *      // ... do something with the series ...
            * }
            * catch (err) {
            *      // ... the dataframe doesn't contain the column "SomeColumn" ...
            * }
            * </pre>
            */
        expectSeries<SeriesValueT>(columnName: string): ISeries<IndexT, SeriesValueT>;
        /**
            * Create a new dataframe with a replaced or additional column specified by the passed-in series.
            *
            * @param columnNameOrSpec The name of the column to add or replace or a {@link IColumnGenSpec} that defines the columns to add.
            * @param [series] When columnNameOrSpec is a string that identifies the column to add, this specifies the {@link Series} to add to the dataframe or a function that produces a series (given a dataframe).
            *
            * @return Returns a new dataframe replacing or adding a particular named column.
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries("ANewColumn", new Series([1, 2, 3]));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries("ANewColumn", df =>
            *      df.getSeries("SourceData").select(aTransformation)
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries({
            *      ANewColumn: new Series([1, 2, 3]),
            *      SomeOtherColumn: new Series([10, 20, 30])
            * });
            * <pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries({
            *      ANewColumn: df => df.getSeries("SourceData").select(aTransformation))
            * });
            * <pre>
            */
        withSeries<OutputValueT = any, SeriesValueT = any>(columnNameOrSpec: string | IColumnGenSpec, series?: ISeries<IndexT, SeriesValueT> | SeriesSelectorFn<IndexT, ValueT, SeriesValueT>): IDataFrame<IndexT, OutputValueT>;
        /**
            * Merge one or more dataframes into this single dataframe.
            * Rows are merged by indexed.
            * Same named columns in subsequent dataframes override columns in earlier dataframes.
            *
            * @param otherDataFrames... One or more dataframes to merge into this dataframe.
            *
            * @returns The merged data frame.
            *
            * @example
            * <pre>
            *
            * const mergedDF = df1.merge(df2);
            * </pre>
            *
            * <pre>
            *
            * const mergedDF = df1.merge(df2, df3, etc);
            * </pre>
            */
        merge<MergedValueT = any>(...otherDataFrames: IDataFrame<IndexT, any>[]): IDataFrame<IndexT, MergedValueT>;
        /**
            * Add a series to the dataframe, but only if it doesn't already exist.
            *
            * @param columnNameOrSpec The name of the series to add or a {@link IColumnGenSpec} that specifies the columns to add.
            * @param [series] If columnNameOrSpec is a string that specifies the name of the series to add, this specifies the actual {@link Series} to add or a selector that generates the series given the dataframe.
            *
            * @return Returns a new dataframe with the specified series added, if the series didn't already exist. Otherwise if the requested series already exists the same dataframe is returned.
            *
            * @example
            * <pre>
            *
            * const updatedDf = df.ensureSeries("ANewColumn", new Series([1, 2, 3]));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const updatedDf = df.ensureSeries("ANewColumn", df =>
            *      df.getSeries("AnExistingSeries").select(aTransformation)
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.ensureSeries({
            *      ANewColumn: new Series([1, 2, 3]),
            *      SomeOtherColumn: new Series([10, 20, 30])
            * });
            * <pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.ensureSeries({
            *      ANewColumn: df => df.getSeries("SourceData").select(aTransformation))
            * });
            * <pre>
            */
        ensureSeries<SeriesValueT>(columnNameOrSpec: string | IColumnGenSpec, series?: ISeries<IndexT, SeriesValueT> | SeriesSelectorFn<IndexT, ValueT, SeriesValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Create a new dataframe with just a subset of columns.
            *
            * @param columnNames Array of column names to include in the new dataframe.
            *
            * @return Returns a dataframe with a subset of columns from the original dataframe.
            *
            * @example
            * <pre>
            * const subsetDf = df.subset(["ColumnA", "ColumnB"]);
            * </pre>
            */
        subset<NewValueT = ValueT>(columnNames: string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Create a new dataframe with the requested column or columns dropped.
            *
            * @param columnOrColumns Specifies the column name (a string) or columns (array of strings) to drop.
            *
            * @return Returns a new dataframe with a particular named column or columns removed.
            *
            * @example
            * <pre>
            * const modifiedDf = df.dropSeries("SomeColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.dropSeries(["ColumnA", "ColumnB"]);
            * </pre>
            */
        dropSeries<NewValueT = ValueT>(columnOrColumns: string | string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Create a new dataframe with columns reordered.
            * New column names create new columns (with undefined values), omitting existing column names causes those columns to be dropped.
            *
            * @param columnNames Specifies the new order for columns.
            *
            * @return Returns a new dataframe with columns reodered according to the order of the array of column names that is passed in.
            *
            * @example
            * <pre>
            * const reorderedDf = df.reorderSeries(["FirstColumn", "SecondColumn", "etc"]);
            * </pre>
            */
        reorderSeries<NewValueT = ValueT>(columnNames: string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Bring the column(s) with specified name(s) to the front of the column order, making it (or them) the first column(s) in the output dataframe.
            *
            * @param columnOrColumns Specifies the column or columns to bring to the front.
            *
            * @return Returns a new dataframe with 1 or more columns bought to the front of the column ordering.
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToFront("NewFirstColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToFront(["NewFirstColumn", "NewSecondColumn"]);
            * </pre>
            */
        bringToFront(columnOrColumns: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Bring the column(s) with specified name(s) to the back of the column order, making it (or them) the last column(s) in the output dataframe.
            *
            * @param columnOrColumns Specifies the column or columns to bring to the back.
            *
            * @return Returns a new dataframe with 1 or more columns bought to the back of the column ordering.
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToBack("NewLastColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToBack(["NewSecondLastCollumn, ""NewLastColumn"]);
            * </pre>
            */
        bringToBack(columnOrColumns: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Create a new dataframe with 1 or more columns renamed.
            *
            * @param newColumnNames A column rename spec - a JavaScript hash that maps existing column names to new column names.
            *
            * @return Returns a new dataframe with specified columns renamed.
            *
            * @example
            * <pre>
            *
            * const renamedDf = df.renameSeries({ OldColumnName, NewColumnName });
            * </pre>
            *
            * @example
            * <pre>
            *
            * const renamedDf = df.renameSeries({
            *      Column1: ColumnA,
            *      Column2: ColumnB
            * });
            * </pre>
            */
        renameSeries<NewValueT = ValueT>(newColumnNames: IColumnRenameSpec): IDataFrame<IndexT, NewValueT>;
        /**
         * Extract rows from the dataframe as an array.
         * Each element of the array is one row of the dataframe represented as
         * a JavaScript object with the fields as the dataframe's columns.
         * This forces lazy evaluation to complete.
         *
         * @return Returns an array of the rows contained within the dataframe.
         *
         * @example
         * <pre>
         * const values = df.toArray();
         * </pre>
         */
        toArray(): ValueT[];
        /**
            * Retreive the index, row pairs from the dataframe as an array.
            * Each pair is [index, row].
            * This forces lazy evaluation to complete.
            *
            * @return Returns an array of pairs that contains the dataframe's rows. Each pair is a two element array that contains an index and a row.
            *
            * @example
            * <pre>
            * const pairs = df.toPairs();
            * </pre>
            */
        toPairs(): ([IndexT, ValueT])[];
        /**
            * Convert the dataframe 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 dataframe by applying the key and value selector functions.
            *
            * @example
            * <pre>
            *
            * const someObject = df.toObject(
            *      row => row.SomeColumn, // Specify the column to use for field names in the output object.
            *      row => row.SomeOtherColumn // Specifi the column 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;
        /**
            * Bake the data frame to an array of rows were each rows is an array of values in column order.
            *
            * @return Returns an array of rows. Each row is an array of values in column order.
            *
            * @example
            * <pre>
            * const rows = df.toRows();
            * </pre>
            */
        toRows(): any[][];
        /**
            * Generates a new dataframe by repeatedly calling a user-defined selector function on each row in the original dataframe.
            *
            * @param selector A user-defined selector function that transforms each row to create the new dataframe.
            *
            * @return Returns a new dataframe with each row transformed by the selector function.
            *
            * @example
            * <pre>
            *
            * function transformRow (inputRow) {
            *      const outputRow = {
            *          // ... construct output row derived from input row ...
            *      };
            *
            *      return outputRow;
            * }
            *
            * const transformedDf = df.select(row => transformRow(row));
            * </pre>
            */
        select<ToT>(selector: SelectorWithIndexFn<ValueT, ToT>): IDataFrame<IndexT, ToT>;
        /**
            * Generates a new dataframe by repeatedly calling a user-defined selector function on each row in the original dataframe.
            *
            * * Similar to the {@link select} function, but in this case the selector function produces a collection of output rows that are flattened and merged to create the new dataframe.
            *
            * @param selector A user-defined selector function that transforms each row into a collection of output rows.
            *
            * @return Returns a new dataframe where each row has been transformed into 0 or more new rows by the selector function.
            *
            * @example
            * <pre>
            *
            * function produceOutputRows (inputRow) {
            *      const outputRows = [];
            *      while (someCondition) {
            *          // ... generate zero or more output rows ...
            *          outputRows.push(... some generated row ...);
            *      }
            *      return outputRows;
            * }
            *
            * const modifiedDf = df.selectMany(row => produceOutputRows(row));
            * </pre>
            */
        selectMany<ToT>(selector: SelectorWithIndexFn<ValueT, Iterable<ToT>>): IDataFrame<IndexT, ToT>;
        /**
            * Transform one or more columns.
            *
            * This is equivalent to extracting a {@link Series} with {@link getSeries}, then transforming it with {@link Series.select},
            * and finally plugging it back in as the same column using {@link withSeries}.
            *
            * @param columnSelectors Object with field names for each column to be transformed. Each field specifies a selector function that transforms that column.
            *
            * @return Returns a new dataframe with 1 or more columns transformed.
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.transformSeries({
            *      AColumnToTransform: columnValue => transformRow(columnValue)
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.transformSeries({
            *      ColumnA: columnValue => transformColumnA(columnValue),
            *      ColumnB: columnValue => transformColumnB(columnValue)
            * });
            * </pre>
            */
        transformSeries<NewValueT = ValueT>(columnSelectors: IColumnTransformSpec): IDataFrame<IndexT, NewValueT>;
        /**
            * Generate new columns based on existing rows.
            *
            * This is equivalent to calling {@link select} to transform the original dataframe to a new dataframe with different column,
            * then using {@link withSeries} to merge each the of both the new and original dataframes.
            *
            * @param generator Generator function that transforms each row to produce 1 or more new columns.
            * Or use a column spec that has fields for each column, the fields specify a generate function that produces the value for each new column.
            *
            * @return Returns a new dataframe with 1 or more new columns.
            *
            * @example
            * <pre>
            *
            * function produceNewColumns (inputRow) {
            *      const newColumns = {
            *          // ... specify new columns and their values based on the input row ...
            *      };
            *
            *      return newColumns;
            * };
            *
            * const dfWithNewSeries = df.generateSeries(row => produceNewColumns(row));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const dfWithNewSeries = df.generateSeries({
            *      NewColumnA: row => produceNewColumnA(row),
            *      NewColumnB: row => produceNewColumnB(row),
            * })
            * </pre>
            */
        generateSeries<NewValueT = ValueT>(generator: SelectorWithIndexFn<any, any> | IColumnTransformSpec): IDataFrame<IndexT, NewValueT>;
        /**
            * Converts (deflates) a dataframe to a {@link Series}.
            *
            * @param [selector] Optional user-defined selector function that transforms each row to produce the series.
            *
            * @return Returns a series that was created from the original dataframe.
            *
            * @example
            * <pre>
            *
            * const series = df.deflate(); // Deflate to a series of object.
            * </pre>
            *
            * @example
            * <pre>
            *
            * const series = df.deflate(row => row.SomeColumn); // Extract a particular column.
            * </pre>
            */
        deflate<ToT = ValueT>(selector?: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
        /**
            * Inflate a named {@link Series} in the dataframe to 1 or more new series in the new dataframe.
            *
            * This is the equivalent of extracting the series using {@link getSeries}, transforming them with {@link Series.select}
            * and then running {@link Series.inflate} to create a new dataframe, then merging each column of the new dataframe
            *  into the original dataframe using {@link withSeries}.
            *
            * @param columnName Name of the series to inflate.
            * @param [selector] Optional selector function that transforms each value in the column to new columns. If not specified it is expected that each value in the column is an object whose fields define the new column names.
            *
            * @return Returns a new dataframe with a column inflated to 1 or more new columns.
            *
            * @example
            * <pre>
            *
            * function newColumnGenerator (row) {
            *      const newColumns = {
            *          // ... create 1 field per new column ...
            *      };
            *
            *      return row;
            * }
            *
            * const dfWithNewSeries = df.inflateSeries("SomeColumn", newColumnGenerator);
            * </pre>
            */
        inflateSeries<NewValueT = ValueT>(columnName: string, selector?: SelectorWithIndexFn<IndexT, any>): IDataFrame<IndexT, ValueT>;
        /**
            * Partition a dataframe into a {@link Series} of *data windows*.
            * Each value in the new series is a chunk of data from the original dataframe.
            *
            * @param period The number of rows to include in each data window.
            *
            * @return Returns a new series, each value of which is a chunk (data window) of the original dataframe.
            *
            * @example
            * <pre>
            *
            * const windows = df.window(2); // Get rows in pairs.
            * const pctIncrease = windows.select(pair => (pair.last().SalesAmount - pair.first().SalesAmount) / pair.first().SalesAmount);
            * 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): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Partition a dataframe into a {@link Series} of *rolling data windows*.
            * Each value in the new series is a rolling chunk of data from the original dataframe.
            *
            * @param period The number of data rows to include in each data window.
            *
            * @return Returns a new series, each value of which is a rolling chunk of the original dataframe.
            *
            * @example
            * <pre>
            *
            * const salesDf = ... // Daily sales data.
            * const rollingWeeklySales = salesDf.rollingWindow(7); // Get rolling window over weekly sales data.
            * console.log(rollingWeeklySales.toString());
            * </pre>
            */
        rollingWindow(period: number): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Partition a dataframe into a {@link 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 rows 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 dataframe.
            *
            * @example
            * <pre>
            *
            * function rowComparer (rowA, rowB) {
            *      if (... rowA should be in the same data window as rowB ...) {
            *          return true;
            *      }
            *      else {
            *          return false;
            *      }
            * };
            *
            * const variableWindows = df.variableWindow(rowComparer);
            */
        variableWindow(comparer: ComparerFn<ValueT, ValueT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Eliminates adjacent duplicate rows.
            *
            * For each group of adjacent values that are equivalent only returns the last index/row for the group,
            * thus ajacent equivalent rows are collapsed down to the last row.
            *
            * @param [selector] Optional selector function to determine the value used to compare for equivalence.
            *
            * @return Returns a new dataframe with groups of adjacent duplicate rows collapsed to a single row per group.
            *
            * @example
            * <pre>
            *
            * const dfWithDuplicateRowsRemoved = df.sequentialDistinct(row => row.ColumnA);
            * </pre>
            */
        sequentialDistinct<ToT = ValueT>(selector?: SelectorFn<ValueT, ToT>): IDataFrame<IndexT, ValueT>;
        /**
            * Aggregate the rows in the dataframe to a single result.
            *
            * @param [seed] Optional seed value for producing the aggregation.
            * @param selector Function that takes the seed and then each row in the dataframe and produces the aggregate value.
            *
            * @return Returns a new value that has been aggregated from the dataframe using the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const dailySalesDf = ... daily sales figures for the past month ...
            * const totalSalesForthisMonth = dailySalesDf.aggregate(
            *      0, // Seed - the starting value.
            *      (accumulator, row) => accumulator + row.SalesAmount // Aggregation function.
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const totalSalesAllTime = 500; // We'll seed the aggregation with this value.
            * const dailySalesDf = ... daily sales figures for the past month ...
            * const updatedTotalSalesAllTime = dailySalesDf.aggregate(
            *      totalSalesAllTime,
            *      (accumulator, row) => accumulator + row.SalesAmount
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * var salesDataSummary = salesDataDf.aggregate({
            *      TotalSales: df => df.count(),
            *      AveragePrice: df => df.deflate(row => row.Price).average(),
            *      TotalRevenue: df => df.deflate(row => row.Revenue).sum(),
            * });
            * </pre>
         */
        aggregate<ToT = ValueT>(seedOrSelector: AggregateFn<ValueT, ToT> | ToT | IColumnAggregateSpec, selector?: AggregateFn<ValueT, ToT>): ToT;
        /**
            * Skip a number of rows in the dataframe.
            *
            * @param numValues Number of rows to skip.
            *
            * @return Returns a new dataframe with the specified number of rows skipped.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skip(10); // Skip 10 rows in the original dataframe.
            * </pre>
            */
        skip(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Skips values in the dataframe while a condition evaluates to true or truthy.
            *
            * @param predicate Returns true/truthy to continue to skip rows in the original dataframe.
            *
            * @return Returns a new dataframe with all initial sequential rows removed while the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skipWhile(row => row.CustomerName === "Fred"); // Skip initial customers named Fred.
            * </pre>
            */
        skipWhile(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Skips values in the dataframe untils a condition evaluates to true or truthy.
            *
            * @param predicate Return true/truthy to stop skipping rows in the original dataframe.
            *
            * @return Returns a new dataframe with all initial sequential rows removed until the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skipUntil(row => row.CustomerName === "Fred"); // Skip initial customers until we find Fred.
            * </pre>
            */
        skipUntil(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Take a number of rows in the dataframe.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe with only the specified number of rows taken from the original dataframe.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.take(15); // Take only the first 15 rows from the original dataframe.
            * </pre>
            */
        take(numRows: number): IDataFrame<IndexT, ValueT>;
        /**
            * Takes values from the dataframe while a condition evaluates to true or truthy.
            *
            * @param predicate Returns true/truthy to continue to take rows from the original dataframe.
            *
            * @return Returns a new dataframe with only the initial sequential rows that were taken while the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.takeWhile(row => row.CustomerName === "Fred"); // Take only initial customers named Fred.
            * </pre>
            */
        takeWhile(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Takes values from the dataframe untils a condition evaluates to true or truthy.
            *
            * @param predicate Return true/truthy to stop taking rows in the original dataframe.
            *
            * @return Returns a new dataframe with only the initial sequential rows taken until the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.takeUntil(row => row.CustomerName === "Fred"); // Take all initial customers until we find Fred.
            * </pre>
            */
        takeUntil(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Count the number of rows in the dataframe
            *
            * @return Returns the count of all rows.
            *
            * @example
            * <pre>
            *
            * const numRows = df.count();
            * </pre>
            */
        count(): number;
        /**
            * Get the first row of the dataframe.
            *
            * @return Returns the first row of the dataframe.
            *
            * @example
            * <pre>
            *
            * const firstRow = df.first();
            * </pre>
            */
        first(): ValueT;
        /**
            * Get the last row of the dataframe.
            *
            * @return Returns the last row of the dataframe.
            *
            * @example
            * <pre>
            *
            * const lastRow = df.last();
            * </pre>
            */
        last(): ValueT;
        /**
            * Get the row, if there is one, with the specified index.
            *
            * @param index Index to for which to retreive the row.
            *
            * @return Returns the row from the specified index in the dataframe or undefined if there is no such index in the present in the dataframe.
            *
            * @example
            * <pre>
            *
            * const row = df.at(5); // Get the row at index 5 (with a default 0-based index).
            * </pre>
            *
            * @example
            * <pre>
            *
            * const date = ... some date ...
            * // Retreive the row with specified date from a time-series dataframe (assuming date indexed has been applied).
            * const row = df.at(date);
            * </pre>
            */
        at(index: IndexT): ValueT | undefined;
        /**
            * Get X rows from the start of the dataframe.
            * Pass in a negative value to get all rows at the head except for X rows at the tail.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe that has only the specified number of rows taken from the start of the original dataframe.
            *
            * @examples
            * <pre>
            *
            * const sample = df.head(10); // Take a sample of 10 rows from the start of the dataframe.
            * </pre>
            */
        head(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Get X rows from the end of the dataframe.
            * Pass in a negative value to get all rows at the tail except X rows at the head.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe that has only the specified number of rows taken from the end of the original dataframe.
            *
            * @examples
            * <pre>
            *
            * const sample = df.tail(12); // Take a sample of 12 rows from the end of the dataframe.
            * </pre>
            */
        tail(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Filter the dataframe using user-defined predicate function.
            *
            * @param predicate Predicte function to filter rows from the dataframe. Returns true/truthy to keep rows, or false/falsy to omit rows.
            *
            * @return Returns a new dataframe containing only the rows from the original dataframe that matched the predicate.
            *
            * @example
            * <pre>
            *
            * const filteredDf = df.where(row => row.CustomerName === "Fred"); // Filter so we only have customers named Fred.
            * </pre>
            */
        where(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Invoke a callback function for each roew in the dataframe.
            *
            * @param callback The calback function to invoke for each row.
            *
            * @return Returns the original dataframe with no modifications.
            *
            * @example
            * <pre>
            *
            * df.forEach(row => {
            *      // ... do something with the row ...
            * });
            * </pre>
            */
        forEach(callback: CallbackFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **all** rows in the dataframe.
            *
            * @param predicate Predicate function that receives each row. It should returns true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned true or truthy for every row in the dataframe, otherwise returns false. Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const everyoneIsNamedFred = df.all(row => row.CustomerName === "Fred"); // Check if all customers are named Fred.
            * </pre>
            */
        all(predicate: PredicateFn<ValueT>): boolean;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **any** of rows in the dataframe.
            *
            * If no predicate is specified then it simply checks if the dataframe contains more than zero rows.
            *
            * @param [predicate] Optional predicate function that receives each row. It should return true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned truthy for any row in the sequence, otherwise returns false.
            * If no predicate is passed it returns true if the dataframe contains any rows at all.
            * Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const anyFreds = df.any(row => row.CustomerName === "Fred"); // Do we have any customers named Fred?
            * </pre>
            *
            * @example
            * <pre>
            *
            * const anyCustomers = df.any(); // Do we have any customers at all?
            * </pre>
            */
        any(predicate?: PredicateFn<ValueT>): boolean;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **none** of rows in the dataframe.
            *
            * If no predicate is specified then it simply checks if the dataframe contains zero rows.
            *
            * @param [predicate] Optional predicate function that receives each row. It should return true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned truthy for zero rows in the dataframe, otherwise returns false. Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const noFreds = df.none(row => row.CustomerName === "Fred"); // Do we have zero customers named Fred?
            * </pre>
            *
            * @example
            * <pre>
            *
            * const noCustomers = df.none(); // Do we have zero customers?
            * </pre>
            */
        none(predicate?: PredicateFn<ValueT>): boolean;
        /**
    * Gets a new dataframe containing all rows starting at and after the specified index value.
    *
    * @param indexValue The index value at which to start the new dataframe.
    *
    * @return Returns a new dataframe containing all rows starting at and after the specified index value.
    *
    * @example
    * <pre>
    *
    * const df = new DataFrame({
    *      index: [0, 1, 2, 3], // This is the default index.
    *      values: [10, 20, 30, 40],
    * });
    *
    * const lastHalf = df.startAt(2);
    * expect(lastHalf.toArray()).to.eql([30, 40]);
    * </pre>
    *
    * @example
    * <pre>
    *
    * const timeSeriesDf = ... a dataframe indexed by date/time ...
    *
    * // Get all rows starting at (or after) a particular date.
    * const allRowsFromStartDate = df.startAt(new Date(2016, 5, 4));
    * </pre>
    */
        startAt(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows up until and including the specified index value (inclusive).
            *
            * @param indexValue The index value at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all rows up until and including the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3], // This is the default index.
            *      values: [10, 20, 30, 40],
            * });
            *
            * const firstHalf = df.endAt(1);
            * expect(firstHalf.toArray()).to.eql([10, 20]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows ending at a particular date.
            * const allRowsUpToAndIncludingTheExactEndDate = df.endAt(new Date(2016, 5, 4));
            * </pre>
            */
        endAt(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows up to the specified index value (exclusive).
            *
            * @param indexValue The index value at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all rows up to (but not including) the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3], // This is the default index.
            *      values: [10, 20, 30, 40],
            * });
            *
            * const firstHalf = df.before(2);
            * expect(firstHalf.toArray()).to.eql([10, 20]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows before the specified date.
            * const allRowsBeforeEndDate = df.before(new Date(2016, 5, 4));
            * </pre>
            */
        before(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows after the specified index value (exclusive).
            *
            * @param indexValue The index value after which to start the new dataframe.
            *
            * @return Returns a new dataframe containing all rows after the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      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 timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows after the specified date.
            * const allRowsAfterStartDate = df.after(new Date(2016, 5, 4));
            * </pre>
            */
        after(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows between the specified index values (inclusive).
            *
            * @param startIndexValue The index at which to start the new dataframe.
            * @param endIndexValue The index at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all values between the specified index values (inclusive).
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3, 4, 6], // This is the default index.
            *      values: [10, 20, 30, 40, 50, 60],
            * });
            *
            * const middleSection = df.between(1, 4);
            * expect(middleSection.toArray()).to.eql([20, 30, 40, 50]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows between the start and end dates (inclusive).
            * const allRowsBetweenDates = df.after(new Date(2016, 5, 4), new Date(2016, 5, 22));
            * </pre>
            */
        between(startIndexValue: IndexT, endIndexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Format the dataframe for display as a string.
            * This forces lazy evaluation to complete.
            *
            * @return Generates and returns a string representation of the dataframe or dataframe.
            *
            * @example
            * <pre>
            *
            * console.log(df.toString());
            * </pre>
            */
        toString(): string;
        /**
            * Parse a column with string values and convert it to a column with int values.
            *
            * @param columnNameOrNames Specifies the column name or array of column names to parse.
            *
            * @return Returns a new dataframe with a particular named column parsed as ints.
            *
            * @example
            * <pre>
            *
            * const withParsedColumn = df.parseInts("MyIntColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const withParsedColumns = df.parseInts(["MyIntColumnA", "MyIntColumnA"]);
            * </pre>
            */
        parseInts(columnNameOrNames: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Parse a column with string values and convert it to a column with float values.
            *
            * @param columnNameOrNames Specifies the column name or array of column names to parse.
            *
            * @return  Returns a new dataframe with a particular named column parsed as floats.
            *
            * @example
            * <pre>
            *
            * const withParsedColumn = df.parseFloats("MyFloatColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const withParsedColumns = df.parseFloats(["MyFloatColumnA", "MyFloatColumnA"]);
            * </pre>
            */
        parseFloats(columnNameOrNames: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Parse a column with string values and convert it to a column with date values.
            *
            * @param columnNameOrNames -Specifies the column name or array of column names to parse.
            * @param [formatString] Optional formatting string for dates.
            *
            * @return Returns a new dataframe with a particular named column parsed as dates.
            *
            * @example
            * <pre>
            *
            * const withParsedColumn = df.parseDates("MyDateColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const withParsedColumns = df.parseDates(["MyDateColumnA", "MyDateColumnA"]);
            * </pre>
            */
        parseDates(columnNameOrNames: string | string[], formatString?: string): IDataFrame<IndexT, ValueT>;
        /**
            * Convert a column of values of different types to a column of string values.
            *
            * @param columnNames Specifies the column name or array of column names to convert to strings. Can also be a format spec that specifies which columns to convert and what their format should be.
            * @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 dataframe with a particular named column convert to strings.
            *
            * @example
            * <pre>
            *
            * const withStringColumn = df.toStrings("MyDateColumn", "YYYY-MM-DD");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const withStringColumn = df.toStrings("MyFloatColumn", "0.00");
            * </pre>
            */
        toStrings(columnNames: string | string[] | IFormatSpec, formatString?: string): IDataFrame<IndexT, ValueT>;
        /**
            * Produces a new dataframe with all string values truncated to the requested maximum length.
            *
            * @param maxLength The maximum length of the string values after truncation.
            *
            * @return Returns a new dataframe with all strings truncated to the specified maximum length.
            *
            * @example
            * <pre>
            *
            * // Truncate all string columns to 100 characters maximum.
            * const truncatedDf = df.truncateString(100);
            * </pre>
            */
        truncateStrings(maxLength: number): IDataFrame<IndexT, ValueT>;
        /**
            * Forces lazy evaluation to complete and 'bakes' the dataframe into memory.
            *
            * @return Returns a dataframe that has been 'baked', all lazy evaluation has completed.
            *
            * @example
            * <pre>
            *
            * const bakedDf = df.bake();
            * </pre>
            */
        bake(): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe in reverse order.
            *
            * @return Returns a new dataframe that is the reverse of the original.
            *
            * @example
            * <pre>
            *
            * const reversed = df.reverse();
            * </pre>
            */
        reverse(): IDataFrame<IndexT, ValueT>;
        /**
            * Returns only the set of rows in the dataframe that are distinct according to some criteria.
            * This can be used to remove duplicate rows from the dataframe.
            *
            * @param selector User-defined selector function that specifies the criteria used to make comparisons for duplicate rows.
            *
            * @return Returns a dataframe containing only unique values as determined by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Remove duplicate rows by customer id. Will return only a single row per customer.
            * const distinctCustomers = salesDf.distinct(sale => sale.CustomerId);
            * </pre>
            */
        distinct<ToT>(selector?: SelectorFn<ValueT, ToT>): IDataFrame<IndexT, ValueT>;
        /**
            * Collects rows in the dataframe into a {@link Series} of groups according to a user-defined selector function.
            *
            * @param selector User-defined selector function that specifies the criteriay to group by.
            *
            * @return Returns a {@link Series} of groups. Each group is a dataframe with rows that have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const salesDf = ... product sales ...
            * const salesByProduct = salesDf.groupBy(sale => sale.ProductId);
            * for (const productSalesGroup of salesByProduct) {
            *      // ... do something with each product group ...
            *      const productId = productSalesGroup.first().ProductId;
            *      const totalSalesForProduct = productSalesGroup.deflate(sale => sale.Amount).sum();
            *      console.log(totalSalesForProduct);
            * }
            * </pre>
            */
        groupBy<GroupT>(selector: SelectorWithIndexFn<ValueT, GroupT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Collects values in the series into a new series of groups based on if the values are the same or according to a user-defined selector function.
            *
            * @param [selector] Optional selector that specifies the criteria for grouping.
            *
            * @return Returns a {@link Series} of groups. Each group is a dataframe with rows that are the same or have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Some ultra simple stock trading strategy backtesting...
            * const dailyStockPriceDf = ... daily stock price for a company ...
            * const priceGroups  = dailyStockPriceDf.groupBy(day => day.close > day.movingAverage);
            * for (const priceGroup of priceGroups) {
            *      // ... do something with each stock price group ...
            *
            *      const firstDay = priceGroup.first();
            *      if (firstDay.close > movingAverage) {
            *          // This group of days has the stock price above its moving average.
            *          // ... maybe enter a long trade here ...
            *      }
            *      else {
            *          // This group of days has the stock price below its moving average.
            *          // ... maybe enter a short trade here ...
            *      }
            * }
            * </pre>
            */
        groupSequentialBy<GroupT>(selector?: SelectorFn<ValueT, GroupT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Concatenate multiple other dataframes onto this dataframe.
            *
            * @param dataframes Multiple arguments. Each can be either a dataframe or an array of dataframes.
            *
            * @return Returns a single dataframe concatenated from multiple input dataframes.
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, c);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat([b, c]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenated = a.concat(b, [c, d]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const otherDfs = [... array of dataframes...];
            * const concatenated = a.concat(otherDfs);
            * </pre>
            */
        concat(...dataframes: (IDataFrame<IndexT, ValueT>[] | IDataFrame<IndexT, ValueT>)[]): IDataFrame<IndexT, ValueT>;
        /**
         * Merge together multiple dataframes to create a new dataframe.
         * Preserves the index of the first dataframe.
         *
         * @param s2, s3, s4, s4 Multiple dataframes to zip.
         * @param zipper User-defined zipper function that merges rows. It produces rows for the new dataframe based-on rows from the input dataframes.
         *
         * @return Returns a single dataframe merged from multiple input dataframes.
         *
         * @example
         * <pre>
         *
         * function produceNewRow (rowA, rowB) {
         *       const outputRow = {
         *           ValueA: rowA.Value,
         *           ValueB: rowB.Value,
         *       };
         *       return outputRow;
         * }
         *
         * const dfA = new DataFrame([ { Value: 10 }, { Value: 20 }, { Value: 30 }]);
         * const dfB = new DataFrame([ { Value: 100 }, { Value: 200 }, { Value: 300 }]);
         * const zippedDf = dfA.zip(dfB, produceNewRow);
         * </pre>
         */
        zip<Index2T, Value2T, ResultT>(s2: IDataFrame<Index2T, Value2T>, zipper: Zip2Fn<ValueT, Value2T, ResultT>): IDataFrame<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, ResultT>(s2: IDataFrame<Index2T, Value2T>, s3: IDataFrame<Index3T, Value3T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): IDataFrame<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, Index4T, Value4T, ResultT>(s2: IDataFrame<Index2T, Value2T>, s3: IDataFrame<Index3T, Value3T>, s4: IDataFrame<Index4T, Value4T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): IDataFrame<IndexT, ResultT>;
        zip<ResultT>(...args: any[]): IDataFrame<IndexT, ResultT>;
        /**
            * Sorts the dataframe in ascending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new dataframe that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by amount from least to most.
            * const orderedDf = salesDf.orderBy(sale => sale.Amount);
            * </pre>
            */
        orderBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
        /**
            * Sorts the dataframe in descending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new dataframe that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by amount from most to least
            * const orderedDf = salesDf.orderByDescending(sale => sale.Amount);
            * </pre>
            */
        orderByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains the union of rows from the two input dataframes.
            * These are the unique combination of rows in both dataframe.
            * This is basically a concatenation and then elimination of duplicates.
            *
            * @param other The other dataframes to merge.
            * @param [selector] Optional user-defined selector function that selects the value to compare to determine distinctness.
            *
            * @return Returns the union of the two dataframes.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const merged = dfA.union(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records that may contain the same
            * // customer record in each set. This is basically a concatenation
            * // of the dataframes and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA.union(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            *
            *
            * @example
            * <pre>
            *
            * // Note that you can achieve the exact same result as the previous
            * // example by doing a {@link DataFrame.concat) and {@link DataFrame.distinct}
            * // of the dataframes and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA
            *      .concat(customerRecordsB)
            *      .distinct(customerRecord => customerRecord.CustomerId);
            * </pre>
            *
            */
        union<KeyT = ValueT>(other: IDataFrame<IndexT, ValueT>, selector?: SelectorFn<ValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains the intersection of rows from the two input dataframes.
            * These are only the rows that appear in both dataframes.
            *
            * @param inner The inner dataframe to merge (the dataframe you call the function on is the 'outer' dataframe).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer dataframe that is used to match the two dataframes.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner dataframe that is used to match the two dataframes.
            *
            * @return Returns a new dataframe that contains the intersection of rows from the two input dataframes.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const mergedDf = dfA.intersection(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records to find only the
            * // customers that appears in both.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const intersectionOfCustomerRecords = customerRecordsA.intersection(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            * */
        intersection<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only the rows from the 1st dataframe that don't appear in the 2nd dataframe.
            * This is essentially subtracting the rows from the 2nd dataframe from the 1st and creating a new dataframe with the remaining rows.
            *
            * @param inner The inner dataframe to merge (the dataframe you call the function on is the 'outer' dataframe).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer dataframe that is used to match the two dataframes.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner dataframe that is used to match the two dataframes.
            *
            * @return Returns a new dataframe that contains only the rows from the 1st dataframe that don't appear in the 2nd dataframe.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const remainingDf = dfA.except(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Find the list of customers haven't bought anything recently.
            * const allCustomers = ... list of all customers ...
            * const recentCustomers = ... list of customers who have purchased recently ...
            * const remainingCustomers = allCustomers.except(
            *      recentCustomers,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        except<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
             * Creates a new dataframe by merging two input dataframes.
             * The resulting dataframe contains only those rows that have matching keys in both input dataframes.
             *
             * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
             * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
             * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
             * @param resultSelector User-defined function that merges outer and inner values.
             *
             * @return Returns the new merged dataframe.
             *
             * @example
             * <pre>
             *
             * // Join together two sets of customers to find those
             * // that have bought both product A and product B.
             * const customerWhoBoughtProductA = ...
             * const customerWhoBoughtProductB = ...
             * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
             *          customerWhoBoughtProductB,
             *          customerA => customerA.CustomerId, // Join key.
             *          customerB => customerB.CustomerId, // Join key.
             *          (customerA, customerB) => {
             *              return {
             *                  // ... merge the results ...
             *              };
             *          }
             *      );
             * </pre>
             */
        join<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT, InnerValueT, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that are only present in or or the other of the dataframes, not both.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either product A or product B, not not both.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const customersWhoBoughtEitherProductButNotBothDf = customerWhoBoughtProductA.joinOuter(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuter<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that are present either in both dataframes or only in the outer (left) dataframe.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product A or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterLeft(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterLeft<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that are present either in both dataframes or only in the inner (right) dataframe.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product B or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterRight(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterRight<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Produces a summary of dataframe. A bit like the 'aggregate' function but much simpler.
            *
            * @param [spec] Optional parameter that specifies which columns to aggregate and how to aggregate them. Leave this out to produce a default summary of all columns.
            *
            * @returns A object with fields that summary the values in the dataframe.
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize();
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Summarize using pre-defined functions.
            *      Column1: Series.sum,
            *      Column2: Series.average,
            *      Column3: Series.count,
            * });
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Summarize using custom functions.
            *      Column1: series => series.sum(),
            *      Column2: series => series.std(),
            *      ColumnN: whateverFunctionYouWant,
            * });
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Multiple output fields per column.
            *      Column1: {
            *          OutputField1: Series.sum,
            *          OutputField2: Series.average,
            *      },
            *      Column2: {
            *          OutputField3: series => series.sum(),
            *          OutputFieldN: whateverFunctionYouWant,
            *      },
            * });
            * console.log(summary);
            * </pre>
            */
        summarize<OutputValueT = any>(spec?: IMultiColumnAggregatorSpec): OutputValueT;
        /**
            * Reshape (or pivot) a dataframe based on column values.
            * This is a powerful function that combines grouping, aggregation and sorting.
            *
            * @param columnOrColumns Column name whose values make the new DataFrame's columns.
            * @param valueColumnNameOrSpec Column name or column spec that defines the columns whose values should be aggregated.
            * @param [aggregator] Optional function used to aggregate pivotted vales.
            *
            * @return Returns a new dataframe that has been pivoted based on a particular column's values.
            *
            * @example
            * <pre>
            *
            * // Simplest example.
            * // Group by the values in 'PivotColumn'.
            * // The column 'ValueColumn' is aggregated for each group and this becomes the
            * // values in the output column.
            * const pivottedDf = df.pivot("PivotColumn", "ValueColumn", values => values.average());
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Multiple input column example.
            * // Similar to the previous example except now we are aggregating multiple input columns.
            * // Each group has the average computed for 'ValueColumnA' and the sum for 'ValueColumnB'.
            * const pivottedDf = df.pivot("PivotColumn", {
            *      ValueColumnA: aValues => aValues.average(),
            *      ValueColumnB:  bValues => bValues.sum(),
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Multiple output column example.
            * // Similar to the previous example except now we are aggregating multiple outputs for each input column.
            * // This example produces an output dataframe with columns OutputColumnA, B, C and D.
            * // OutputColumnA/B are the sum and average of ValueColumnA across each group as defined by PivotColumn.
            * // OutputColumnC/D are the sum and average of ValueColumnB across each group as defined by PivotColumn.
            * const pivottedDf = df.pivot("PivotColumn", {
            *      ValueColumnA: {
            *          OutputColumnA: aValues => aValues.sum(),
            *          OutputColumnB: aValues => aValues.average(),
            *      },
            *      ValueColumnB: {
            *          OutputColumnC: bValues => aValues.sum(),
            *          OutputColumnD: bValues => aValues.average(),
            *      },
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Full multi-column example.
            * // Similar to the previous example, but now we are pivotting on multiple columns.
            * // We now group by 'PivotColumnA' and then by 'PivotColumnB', effectively creating a
            * // multi-level nested group.
            * const pivottedDf = df.pivot(["PivotColumnA", "PivotColumnB" ], {
            *      ValueColumnA: aValues => aValues.average(),
            *      ValueColumnB:  bValues => bValues.sum(),
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // To help understand the pivot function, let's expand it out and look at what it does internally.
            * // Take the simplest example:
            * const pivottedDf = df.pivot("PivotColumn", "ValueColumn", values => values.average());
            *
            * // If we expand out the internals of the pivot function, it will look something like this:
            * const pivottedDf = df.groupBy(row => row.PivotColumn)
            *          .select(group => ({
            *              PivotColumn: group.first().PivotColumn,
            *              ValueColumn: group.deflate(row => row.ValueColumn).average()
            *          }))
            *          .orderBy(row  => row.PivotColumn);
            *
            * // You can see that pivoting a dataframe is the same as grouping, aggregating and sorting it.
            * // Does pivoting seem simpler now?
            *
            * // It gets more complicated than that of course, because the pivot function supports multi-level nested
            * // grouping and aggregation of multiple columns. So a full expansion of the pivot function is rather complex.
            * </pre>
            */
        pivot<NewValueT = ValueT>(columnOrColumns: string | Iterable<string>, valueColumnNameOrSpec: string | IMultiColumnAggregatorSpec, aggregator?: (values: ISeries<number, any>) => any): IDataFrame<number, NewValueT>;
        /**
            * Insert a pair at the start of the dataframe.
            * Doesn't modify the original dataframe! The returned dataframe is entirely new and contains rows from the original dataframe plus the inserted pair.
            *
            * @param pair The index/value pair to insert.
            *
            * @return Returns a new dataframe with the specified pair inserted.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to insert ...
            * const insertedDf = df.insertPair([newIndex, newRows]);
            * </pre>
            */
        insertPair(pair: [IndexT, ValueT]): IDataFrame<IndexT, ValueT>;
        /**
            * Append a pair to the end of a dataframe.
            * Doesn't modify the original dataframe! The returned dataframe is entirely new and contains rows from the original dataframe plus the appended pair.
            *
            * @param pair The index/value pair to append.
            *
            * @return Returns a new dataframe with the specified pair appended.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to append ...
            * const appendedDf = df.appendPair([newIndex, newRows]);
            * </pre>
            */
        appendPair(pair: [IndexT, ValueT]): IDataFrame<IndexT, ValueT>;
        /**
            * Fill gaps in a dataframe.
            *
            * @param comparer User-defined comparer function that is passed pairA and pairB, two consecutive rows, return truthy if there is a gap between the rows, or falsey if there is no gap.
            * @param generator User-defined generator function that is passed pairA and pairB, two consecutive rows, returns an array of pairs that fills the gap between the rows.
            *
            * @return Returns a new dataframe with gaps filled in.
            *
            * @example
            * <pre>
            *
            *   var sequenceWithGaps = ...
            *
            *  // Predicate that determines if there is a gap.
            *  var gapExists = (pairA, pairB) => {
            *      // Returns true if there is a gap.
            *      return true;
            *  };
            *
            *  // Generator function that produces new rows to fill the game.
            *  var gapFiller = (pairA, pairB) => {
            *      // Create an array of index, value pairs that fill the gaps between pairA and pairB.
            *      return [
            *          newPair1,
            *          newPair2,
            *          newPair3,
            *      ];
            *  };
            *
            *  var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller);
            * </pre>
            */
        fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): IDataFrame<IndexT, ValueT>;
        /**
            * Returns the specified default dataframe if the input dataframe is empty.
            *
            * @param defaultSequence Default dataframe to return if the input dataframe is empty.
            *
            * @return Returns 'defaultSequence' if the input dataframe is empty.
            *
            * @example
            * <pre>
            *
            * const emptyDataFrame = new DataFrame();
            * const defaultDataFrame = new DataFrame([ { A: 1 }, { A: 2 }, { A: 3 } ]);
            * expect(emptyDataFrame.defaultIfEmpty(defaultDataFrame)).to.eql(defaultDataFrame);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const nonEmptyDataFrame = new DataFrame([ { A: 100 }]);
            * const defaultDataFrame = new DataFrame([ { A: 1 }, { A: 2 }, { A: 3 } ]);
            * expect(nonEmptyDataFrame.defaultIfEmpty(defaultDataFrame)).to.eql(nonEmptyDataFrame);
            * </pre>
            */
        defaultIfEmpty(defaultSequence: ValueT[] | IDataFrame<IndexT, ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Detect the the frequency of the types of the values in the dataframe.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a dataframe with rows that confirm to {@link ITypeFrequency} that describes the data types contained in the original dataframe.
            *
            * @example
            * <pre>
            *
            * const df = dataForge.readFileSync("./my-data.json").parseJSON();
            * const dataTypes = df.detectTypes();
            * console.log(dataTypes.toString());
            * </pre>
            */
        detectTypes(): IDataFrame<number, ITypeFrequency>;
        /**
            * Detect the frequency of the values in the dataframe.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a dataframe with rows that conform to {@link IValueFrequency} that describes the values contained in the original dataframe.
            *
            * @example
            * <pre>
            *
            * const df = dataForge.readFileSync("./my-data.json").parseJSON();
            * const dataValues = df.detectValues();
            * console.log(dataValues.toString());
            * </pre>
            */
        detectValues(): IDataFrame<number, IValueFrequency>;
        /**
            * Serialize the dataframe to the JSON data format.
            *
            * @return Returns a string in the JSON data format that represents the dataframe.
            *
            * @example
            * <pre>
            *
            * const jsonData = df.toJSON();
            * console.log(jsonData);
            * </pre>
            */
        toJSON(): string;
        /**
            * Serialize the dataframe to the CSV data format.
            *
            * @return Returns a string in the CSV data format that represents the dataframe.
            *
            * @example
            * <pre>
            *
            * const csvData = df.toCSV();
            * console.log(csvData);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const csvData = df.toCSV({ header: false });
            * console.log(csvData);
            * </pre>
            */
        toCSV(options?: ICSVOutputOptions): string;
        /**
            * Serialize the dataframe to HTML.
            *
            * @return Returns a string in HTML format that represents the dataframe.
            */
        toHTML(): string;
        /**
            * Serialize the dataframe to an ordinary JavaScript data structure.
            * The resulting data structure is suitable for further serialization to JSON and can be used to
            * transmit a DataFrame and its internal structure over the wire.
            * Use the {@link deserialize} function to later reconstitute the serialized dataframe.
            *
            * @return Returns a JavaScript data structure conforming to {@link ISerializedDataFrame} that represents the dataframe and its internal structure.
            *
            * @example
            * <pre>
            *
            * const jsDataStructure = df.serialize();
            * const jsonData = JSON.stringify(jsDataStructure);
            * console.log(jsonData);
            * const deserializedJsDataStructure = JSON.parse(jsonData);
            * const deserializedDf = DataFrame.deserialize(deserializedJsDataStructure); // Reconsituted.
            * </pre>
            */
        serialize(): any;
}
/**
    * Interface to a dataframe that has been sorted.
    */
export interface IOrderedDataFrame<IndexT = number, ValueT = any, SortT = any> extends IDataFrame<IndexT, ValueT> {
        /**
            * Applys additional sorting (ascending) to an already sorted dataframe.
            *
            * @param selector User-defined selector that selects the additional value to sort by.
            *
            * @return Returns a new dataframe has been additionally sorted by the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by salesperson and then by amount (from least to most).
            * const orderedDf = salesDf.orderBy(sale => sale.SalesPerson).thenBy(sale => sale.Amount);
            * </pre>
            */
        thenBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
        /**
            * Applys additional sorting (descending) to an already sorted dataframe.
            *
            * @param selector User-defined selector that selects the additional value to sort by.
            *
            * @return Returns a new dataframe has been additionally sorted by the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by salesperson and then by amount (from most to least).
            * const orderedDf = salesDf.orderBy(sale => sale.SalesPerson).thenByDescending(sale => sale.Amount);
            * </pre>
            */
        thenByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
}
/**
    * Class that represents a dataframe.
    * A dataframe contains an indexed sequence of data records.
    * Think of it as a spreadsheet or CSV file in memory.
    *
    * Each data record contains multiple named fields, the value of each field represents one row in a column of data.
    * Each column of data is a named {@link Series}.
    * You think of a dataframe a collection of named data series.
    *
    * @typeparam IndexT The type to use for the index.
    * @typeparam ValueT The type to use for each row/data record.
    */
export declare class DataFrame<IndexT = number, ValueT = any> implements IDataFrame<IndexT, ValueT> {
        /**
            * Create a dataframe.
            *
            * @param config This can be an array, a configuration object or a function that lazily produces a configuration object.
            *
            * It can be an array that specifies the data records that the dataframe contains.
            *
            * It can be a {@link IDataFrameConfig} that defines the data and configuration of the dataframe.
            *
            * Or it can be a function that lazily produces a {@link IDataFrameConfig}.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame();
            * </pre>
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame([ { A: 10 }, { A: 20 }, { A: 30 }, { A: 40 }]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({ index: [1, 2, 3, 4], values: [ { A: 10 }, { A: 20 }, { A: 30 }, { A: 40 }] });
            * </pre>
            *
            * @example
            * <pre>
            *
            * const lazyInit = () => ({ index: [1, 2, 3, 4], values: [ { A: 10 }, { A: 20 }, { A: 30 }, { A: 40 }] });
            * const df = new DataFrame(lazyInit);
            * </pre>
            */
        constructor(config?: Iterable<ValueT> | IDataFrameConfig<IndexT, ValueT> | DataFrameConfigFn<IndexT, ValueT>);
        /**
            * Get an iterator to enumerate the rows of the dataframe.
            * Enumerating the iterator forces lazy evaluation to complete.
            * This function is automatically called by `for...of`.
            *
            * @return An iterator for the dataframe.
            *
            * @example
            * <pre>
            *
            * for (const row of df) {
            *     // ... do something with the row ...
            * }
            * </pre>
            */
        [Symbol.iterator](): Iterator<any>;
        /**
            * Get the names of the columns in the dataframe.
            *
            * @return Returns an array of the column names in the dataframe.
            *
            * @example
            * <pre>
            *
            * console.log(df.getColumnNames());
            * </pre>
            */
        getColumnNames(): string[];
        /**
            * Retreive the collection of all columns in the dataframe.
            *
            * @return Returns a {@link Series} containing the names of the columns in the dataframe.
            *
            * @example
            * <pre>
            *
            * for (const column in df.getColummns()) {
            *      console.log("Column name: ");
            *      console.log(column.name);
            *
            *      console.log("Data:");
            *      console.log(column.series.toArray());
            * }
            * </pre>
            */
        getColumns(): ISeries<number, IColumn>;
        /**
            * Cast the value of the dataframe to a new type.
            * This operation has no effect but to retype the value that the dataframe contains.
            *
            * @return The same dataframe, but with the type changed.
            *
            * @example
            * <pre>
            *
            * const castDf = df.cast<SomeOtherType>();
            * </pre>
            */
        cast<NewValueT>(): IDataFrame<IndexT, NewValueT>;
        /**
            * Get the index for the dataframe.
            *
            * @return The {@link Index} for the dataframe.
            *
            * @example
            * <pre>
            *
            * const index = df.getIndex();
            * </pre>
            */
        getIndex(): IIndex<IndexT>;
        /**
            * Set a named column as the {@link Index} of the dataframe.
            *
            * @param columnName Name of the column to use as the new {@link Index} of the returned dataframe.
            *
            * @return Returns a new dataframe with the values of the specified column as the new {@link Index}.
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.setIndex("SomeColumn");
            * </pre>
            */
        setIndex<NewIndexT = any>(columnName: string): IDataFrame<NewIndexT, ValueT>;
        /**
            * Apply a new {@link Index} to the dataframe.
            *
            * @param newIndex The new array or iterable to be the new {@link Index} of the dataframe. Can also be a selector to choose the {@link Index} for each row in the dataframe.
            *
            * @return Returns a new dataframe or dataframe with the specified {@link Index} attached.
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex([10, 20, 30]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(df.getSeries("SomeColumn"));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(row => row.SomeColumn);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const indexedDf = df.withIndex(row => row.SomeColumn + 20);
            * </pre>
            */
        withIndex<NewIndexT>(newIndex: Iterable<NewIndexT> | SelectorFn<ValueT, NewIndexT>): IDataFrame<NewIndexT, ValueT>;
        /**
            * Resets the {@link Index} of the dataframe back to the default zero-based sequential integer index.
            *
            * @return Returns a new dataframe with the {@link Index} reset to the default zero-based index.
            *
            * @example
            * <pre>
            *
            * const dfWithResetIndex = df.resetIndex();
            * </pre>
            */
        resetIndex(): IDataFrame<number, ValueT>;
        /**
            * Extract a {@link Series} from a named column in the dataframe.
            *
            * @param columnName Specifies the name of the column that contains the {@link Series} to retreive.
            *
            * @return Returns the {@link Series} extracted from the named column in the dataframe.
            *
            * @example
            * <pre>
            *
            * const series = df.getSeries("SomeColumn");
            * </pre>
            */
        getSeries<SeriesValueT = any>(columnName: string): ISeries<IndexT, SeriesValueT>;
        /**
            * Determine if the dataframe contains a {@link Series} the specified named column.
            *
            * @param columnName Name of the column to check for.
            *
            * @return Returns true if the dataframe contains the requested {@link Series}, otherwise returns false.
            *
            * @example
            * <pre>
            *
            * if (df.hasSeries("SomeColumn")) {
            *      // ... the dataframe contains a series with the specified column name ...
            * }
            * </pre>
            */
        hasSeries(columnName: string): boolean;
        /**
            * Verify the existence of a name column and extracts the {@link Series} for it.
            * Throws an exception if the requested column doesn't exist.
            *
            * @param columnName Name of the column to extract.
            *
            * @return Returns the {@link Series} for the column if it exists, otherwise it throws an exception.
            *
            * @example
            * <pre>
            *
            * try {
            *      const series = df.expectSeries("SomeColumn");
            *      // ... do something with the series ...
            * }
            * catch (err) {
            *      // ... the dataframe doesn't contain the column "SomeColumn" ...
            * }
            * </pre>
            */
        expectSeries<SeriesValueT>(columnName: string): ISeries<IndexT, SeriesValueT>;
        /**
            * Create a new dataframe with a replaced or additional column specified by the passed-in series.
            *
            * @param columnNameOrSpec The name of the column to add or replace or a {@link IColumnGenSpec} that defines the columns to add.
            * @param [series] When columnNameOrSpec is a string that identifies the column to add, this specifies the {@link Series} to add to the dataframe or a function that produces a series (given a dataframe).
            *
            * @return Returns a new dataframe replacing or adding a particular named column.
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries("ANewColumn", new Series([1, 2, 3]));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries("ANewColumn", df =>
            *      df.getSeries("SourceData").select(aTransformation)
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries({
            *      ANewColumn: new Series([1, 2, 3]),
            *      SomeOtherColumn: new Series([10, 20, 30])
            * });
            * <pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.withSeries({
            *      ANewColumn: df => df.getSeries("SourceData").select(aTransformation))
            * });
            * <pre>
            */
        withSeries<OutputValueT = any, SeriesValueT = any>(columnNameOrSpec: string | IColumnGenSpec, series?: ISeries<IndexT, SeriesValueT> | SeriesSelectorFn<IndexT, ValueT, SeriesValueT>): IDataFrame<IndexT, OutputValueT>;
        /**
            * Merge multiple dataframes into a single dataframe.
            * Rows are merged by indexed.
            * Same named columns in subsequent dataframes override columns earlier dataframes.
            *
            * @param dataFrames An array or series of dataframes to merge.
            *
            * @returns The merged data frame.
            *
            * @example
            * <pre>
            *
            * const mergedDF = DataFrame.merge([df1, df2, etc]);
            * </pre>
            */
        static merge<MergedValueT = any, IndexT = any, ValueT = any>(dataFrames: Iterable<IDataFrame<IndexT, ValueT>>): IDataFrame<IndexT, MergedValueT>;
        /**
            * Merge one or more dataframes into this dataframe.
            * Rows are merged by indexed.
            * Same named columns in subsequent dataframes override columns in earlier dataframes.
            *
            * @param otherDataFrames... One or more dataframes to merge into this dataframe.
            *
            * @returns The merged data frame.
            *
            * @example
            * <pre>
            *
            * const mergedDF = df1.merge(df2);
            * </pre>
            *
            * <pre>
            *
            * const mergedDF = df1.merge(df2, df3, etc);
            * </pre>
            */
        merge<MergedValueT = ValueT>(...otherDataFrames: IDataFrame<IndexT, any>[]): IDataFrame<IndexT, MergedValueT>;
        /**
            * Add a series to the dataframe, but only if it doesn't already exist.
            *
            * @param columnNameOrSpec The name of the series to add or a {@link IColumnGenSpec} that specifies the columns to add.
            * @param [series] If columnNameOrSpec is a string that specifies the name of the series to add, this specifies the actual {@link Series} to add or a selector that generates the series given the dataframe.
            *
            * @return Returns a new dataframe with the specified series added, if the series didn't already exist. Otherwise if the requested series already exists the same dataframe is returned.
            *
            * @example
            * <pre>
            *
            * const updatedDf = df.ensureSeries("ANewColumn", new Series([1, 2, 3]));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const updatedDf = df.ensureSeries("ANewColumn", df =>
            *      df.getSeries("AnExistingSeries").select(aTransformation)
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.ensureSeries({
            *      ANewColumn: new Series([1, 2, 3]),
            *      SomeOtherColumn: new Series([10, 20, 30])
            * });
            * <pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.ensureSeries({
            *      ANewColumn: df => df.getSeries("SourceData").select(aTransformation))
            * });
            * <pre>
            */
        ensureSeries<SeriesValueT>(columnNameOrSpec: string | IColumnGenSpec, series?: ISeries<IndexT, SeriesValueT> | SeriesSelectorFn<IndexT, ValueT, SeriesValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Create a new dataframe with just a subset of columns.
            *
            * @param columnNames Array of column names to include in the new dataframe.
            *
            * @return Returns a dataframe with a subset of columns from the original dataframe.
            *
            * @example
            * <pre>
            * const subsetDf = df.subset(["ColumnA", "ColumnB"]);
            * </pre>
            */
        subset<NewValueT = ValueT>(columnNames: string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Create a new dataframe with the requested column or columns dropped.
            *
            * @param columnOrColumns Specifies the column name (a string) or columns (array of strings) to drop.
            *
            * @return Returns a new dataframe with a particular named column or columns removed.
            *
            * @example
            * <pre>
            * const modifiedDf = df.dropSeries("SomeColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.dropSeries(["ColumnA", "ColumnB"]);
            * </pre>
            */
        dropSeries<NewValueT = ValueT>(columnOrColumns: string | string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Create a new dataframe with columns reordered.
            * New column names create new columns (with undefined values), omitting existing column names causes those columns to be dropped.
            *
            * @param columnNames Specifies the new order for columns.
            *
            * @return Returns a new dataframe with columns reodered according to the order of the array of column names that is passed in.
            *
            * @example
            * <pre>
            * const reorderedDf = df.reorderSeries(["FirstColumn", "SecondColumn", "etc"]);
            * </pre>
            */
        reorderSeries<NewValueT = ValueT>(columnNames: string[]): IDataFrame<IndexT, NewValueT>;
        /**
            * Bring the column(s) with specified name(s) to the front of the column order, making it (or them) the first column(s) in the output dataframe.
            *
            * @param columnOrColumns Specifies the column or columns to bring to the front.
            *
            * @return Returns a new dataframe with 1 or more columns bought to the front of the column ordering.
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToFront("NewFirstColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToFront(["NewFirstColumn", "NewSecondColumn"]);
            * </pre>
            */
        bringToFront(columnOrColumns: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Bring the column(s) with specified name(s) to the back of the column order, making it (or them) the last column(s) in the output dataframe.
            *
            * @param columnOrColumns Specifies the column or columns to bring to the back.
            *
            * @return Returns a new dataframe with 1 or more columns bought to the back of the column ordering.
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToBack("NewLastColumn");
            * </pre>
            *
            * @example
            * <pre>
            * const modifiedDf = df.bringToBack(["NewSecondLastCollumn, ""NewLastColumn"]);
            * </pre>
            */
        bringToBack(columnOrColumns: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Create a new dataframe with 1 or more columns renamed.
            *
            * @param newColumnNames A column rename spec - a JavaScript hash that maps existing column names to new column names.
            *
            * @return Returns a new dataframe with specified columns renamed.
            *
            * @example
            * <pre>
            *
            * const renamedDf = df.renameSeries({ OldColumnName, NewColumnName });
            * </pre>
            *
            * @example
            * <pre>
            *
            * const renamedDf = df.renameSeries({
            *      Column1: ColumnA,
            *      Column2: ColumnB
            * });
            * </pre>
            */
        renameSeries<NewValueT = ValueT>(newColumnNames: IColumnRenameSpec): IDataFrame<IndexT, NewValueT>;
        /**
         * Extract values from the dataframe as an array.
         * This forces lazy evaluation to complete.
         *
         * @return Returns an array of the values contained within the dataframe.
         *
         * @example
         * <pre>
         * const values = df.toArray();
         * </pre>
         */
        toArray(): any[];
        /**
            * Retreive the index and values pairs from the dataframe as an array.
            * Each pair is [index, value].
            * This forces lazy evaluation to complete.
            *
            * @return Returns an array of pairs that contains the dataframe content. Each pair is a two element array that contains an index and a value.
            *
            * @example
            * <pre>
            * const pairs = df.toPairs();
            * </pre>
            */
        toPairs(): ([IndexT, ValueT])[];
        /**
            * Convert the dataframe to a JavaScript object.
            *
            * @param keySelector Function that selects keys for the resulting object.
            * @param valueSelector Function that selects values for the resulting object.
            *
            * @return Returns a JavaScript object generated from the dataframe by applying the key and value selector functions.
            *
            * @example
            * <pre>
            *
            * const someObject = df.toObject(
            *      row => row.SomeColumn, // Specify the column to use for fields in the object.
            *      row => row.SomeOtherColumn // Specifi the column 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;
        /**
            * Bake the data frame to an array of rows were each rows is an array of values in column order.
            *
            * @return Returns an array of rows. Each row is an array of values in column order.
            *
            * @example
            * <pre>
            * const rows = df.toRows();
            * </pre>
            */
        toRows(): any[][];
        /**
            * Generates a new dataframe by repeatedly calling a selector function on each row in the original dataframe.
            *
            * @param selector Selector function that transforms each row to create the new dataframe.
            *
            * @return Returns a new dataframe that has been transformed by the selector function.
            *
            * @example
            * <pre>
            *
            * function transformRow (inputRow) {
            *      const outputRow = {
            *          // ... construct output row derived from input row ...
            *      };
            *
            *      return outputRow;
            * }
            *
            * const modifiedDf = df.select(row => transformRow(row));
            * </pre>
            */
        select<ToT>(selector: SelectorWithIndexFn<ValueT, ToT>): IDataFrame<IndexT, ToT>;
        /**
            * Generates a new dataframe by repeatedly calling a selector function on each row in the original dataframe.
            *
            * In this case the selector function produces a collection of output rows that are flattened to create the new dataframe.
            *
            * @param selector Selector function that transforms each row into a collection of output rows.
            *
            * @return  Returns a new dataframe with rows that have been produced by the selector function.
            *
            * @example
            * <pre>
            *
            * function produceOutputRows (inputRow) {
            *      const outputRows = [];
            *      while (someCondition) {     *
            *          // ... generate zero or more output rows ...
            *          outputRows.push(... some generated row ...);
            *      }
            *      return outputRows;
            * }
            *
            * const modifiedDf = df.selectMany(row => produceOutputRows(row));
            * </pre>
            */
        selectMany<ToT>(selector: SelectorWithIndexFn<ValueT, Iterable<ToT>>): IDataFrame<IndexT, ToT>;
        /**
            * Transform one or more columns.
            *
            * This is equivalent to extracting a {@link Series} with {@link getSeries}, then transforming it with {@link Series.select},
            * and finally plugging it back in as the same column using {@link withSeries}.
            *
            * @param columnSelectors Object with field names for each column to be transformed. Each field specifies a selector function that transforms that column.
            *
            * @return Returns a new dataframe with 1 or more columns transformed.
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.transformSeries({
            *      AColumnToTransform: columnValue => transformRow(columnValue)
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * const modifiedDf = df.transformSeries({
            *      ColumnA: columnValue => transformColumnA(columnValue),
            *      ColumnB: columnValue => transformColumnB(columnValue)
            * });
            * </pre>
            */
        transformSeries<NewValueT = ValueT>(columnSelectors: IColumnTransformSpec): IDataFrame<IndexT, NewValueT>;
        /**
            * Generate new columns based on existing rows.
            *
            * This is equivalent to calling {@link select} to transform the original dataframe to a new dataframe with different column,
            * then using {@link withSeries} to merge each the of both the new and original dataframes.
            *
            * @param generator Generator function that transforms each row to produce 1 or more new columns.
            * Or use a column spec that has fields for each column, the fields specify a generate function that produces the value for each new column.
            *
            * @return Returns a new dataframe with 1 or more new columns.
            *
            * @example
            * <pre>
            *
            * function produceNewColumns (inputRow) {
            *      const newColumns = {
            *          // ... specify new columns and their values based on the input row ...
            *      };
            *
            *      return newColumns;
            * };
            *
            * const dfWithNewSeries = df.generateSeries(row => produceNewColumns(row));
            * </pre>
            *
            * @example
            * <pre>
            *
            * const dfWithNewSeries = df.generateSeries({
            *      NewColumnA: row => produceNewColumnA(row),
            *      NewColumnB: row => produceNewColumnB(row),
            * })
            * </pre>
            */
        generateSeries<NewValueT = ValueT>(generator: SelectorWithIndexFn<any, any> | IColumnTransformSpec): IDataFrame<IndexT, NewValueT>;
        /**
            * Converts (deflates) a dataframe to a {@link Series}.
            *
            * @param [selector] Optional selector function that transforms each row to produce the series.
            *
            * @return Returns a series that was created from the deflated from  the original dataframe.
            *
            * @example
            * <pre>
            *
            * const series = df.deflate(); // Deflate to a series of object.
            * </pre>
            *
            * @example
            * <pre>
            *
            * const series = df.deflate(row => row.SomeColumn); // Extract a particular column.
            * </pre>
            */
        deflate<ToT = ValueT>(selector?: SelectorWithIndexFn<ValueT, ToT>): ISeries<IndexT, ToT>;
        /**
            * Inflate a named {@link Series} in the dataframe to 1 or more new series in the new dataframe.
            *
            * This is the equivalent of extracting the series using {@link getSeries}, transforming them with {@link Series.select}
            * and then running {@link Series.inflate} to create a new dataframe, then merging each column of the new dataframe
            *  into the original dataframe using {@link withSeries}.
            *
            * @param columnName Name of the series to inflate.
            * @param [selector] Optional selector function that transforms each value in the column to new columns. If not specified it is expected that each value in the column is an object whose fields define the new column names.
            *
            * @return Returns a new dataframe with a column inflated to 1 or more new columns.
            *
            * @example
            * <pre>
            *
            * function newColumnGenerator (row) {
            *      const newColumns = {
            *          // ... create 1 field per new column ...
            *      };
            *
            *      return row;
            * }
            *
            * const dfWithNewSeries = df.inflateSeries("SomeColumn", newColumnGenerator);
            * </pre>
            */
        inflateSeries<NewValueT = ValueT>(columnName: string, selector?: SelectorWithIndexFn<IndexT, any>): IDataFrame<IndexT, ValueT>;
        /**
            * Partition a dataframe into a {@link Series} of *data windows*.
            * Each value in the new series is a rolling chunk of data from the original dataframe.
            *
            * @param period The number of data rows to include in each data window.
            *
            * @return Returns a new series, each value of which is a chunk of the original dataframe.
            *
            * @example
            * <pre>
            *
            * const windows = df.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): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Partition a dataframe into a {@link Series} of *rolling data windows*.
            * Each value in the new series is a rolling chunk of data from the original dataframe.
            *
            * @param period The number of data rows to include in each data window.
            *
            * @return Returns a new series, each value of which is a rolling chunk of the original dataframe.
            *
            * @example
            * <pre>
            *
            * const salesDf = ... // Daily sales data.
            * const rollingWeeklySales = salesDf.rollingWindow(7); // Get rolling window over weekly sales data.
            * console.log(rollingWeeklySales.toString());
            * </pre>
            */
        rollingWindow(period: number): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Partition a dataframe into a {@link 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 rows 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 dataframe.
            *
            * @example
            * <pre>
            *
            * function rowComparer (rowA, rowB) {
            *      if (... rowA should be in the same data window as rowB ...) {
            *          return true;
            *      }
            *      else {
            *          return false;
            *      }
            * };
            *
            * const variableWindows = df.variableWindow(rowComparer);
            */
        variableWindow(comparer: ComparerFn<ValueT, ValueT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Eliminates adjacent duplicate rows.
            *
            * For each group of adjacent rows that are equivalent only returns the last index/row for the group,
            * thus ajacent equivalent rows are collapsed down to the last row.
            *
            * @param [selector] Optional selector function to determine the value used to compare for equivalence.
            *
            * @return Returns a new dataframe with groups of adjacent duplicate rows collapsed to a single row per group.
            *
            * @example
            * <pre>
            *
            * const dfWithDuplicateRowsRemoved = df.sequentialDistinct(row => row.ColumnA);
            * </pre>
            */
        sequentialDistinct<ToT = ValueT>(selector?: SelectorFn<ValueT, ToT>): IDataFrame<IndexT, ValueT>;
        /**
            * Aggregate the rows in the dataframe to a single result.
            *
            * @param [seed] Optional seed value for producing the aggregation.
            * @param selector Function that takes the seed and then each row in the dataframe and produces the aggregated value.
            *
            * @return Returns a new value that has been aggregated from the dataframe using the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const dailySalesDf = ... daily sales figures for the past month ...
            * const totalSalesForthisMonth = dailySalesDf.aggregate(
            *      0, // Seed - the starting value.
            *      (accumulator, row) => accumulator + row.SalesAmount // Aggregation function.
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * const totalSalesAllTime = 500; // We'll seed the aggregation with this value.
            * const dailySalesDf = ... daily sales figures for the past month ...
            * const updatedTotalSalesAllTime = dailySalesDf.aggregate(
            *      totalSalesAllTime,
            *      (accumulator, row) => accumulator + row.SalesAmount
            * );
            * </pre>
            *
            * @example
            * <pre>
            *
            * var salesDataSummary = salesDataDf.aggregate({
            *      TotalSales: df => df.count(),
            *      AveragePrice: df => df.deflate(row => row.Price).average(),
            *      TotalRevenue: df => df.deflate(row => row.Revenue).sum(),
            * });
            * </pre>
         */
        aggregate<ToT = ValueT>(seedOrSelector: AggregateFn<ValueT, ToT> | ToT | IColumnAggregateSpec, selector?: AggregateFn<ValueT, ToT>): ToT;
        /**
            * Skip a number of rows in the dataframe.
            *
            * @param numValues Number of rows to skip.
            *
            * @return Returns a new dataframe with the specified number of rows skipped.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skip(10); // Skip 10 rows in the original dataframe.
            * </pre>
            */
        skip(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Skips rows in the dataframe while a condition evaluates to true or truthy.
            *
            * @param predicate Returns true/truthy to continue to skip rows in the original dataframe.
            *
            * @return Returns a new dataframe with all initial sequential rows removed while the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skipWhile(row => row.CustomerName === "Fred"); // Skip initial customers named Fred.
            * </pre>
            */
        skipWhile(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Skips rows in the dataframe untils a condition evaluates to true or truthy.
            *
            * @param predicate Return true/truthy to stop skipping rows in the original dataframe.
            *
            * @return Returns a new dataframe with all initial sequential rows removed until the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsSkipped = df.skipUntil(row => row.CustomerName === "Fred"); // Skip initial customers until we find Fred.
            * </pre>
            */
        skipUntil(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Take a number of rows from the dataframe.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe with only the specified number of rows taken from the original dataframe.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.take(15); // Take only the first 15 rows from the original dataframe.
            * </pre>
            */
        take(numRows: number): IDataFrame<IndexT, ValueT>;
        /**
            * Takes rows from the dataframe while a condition evaluates to true or truthy.
            *
            * @param predicate Returns true/truthy to continue to take rows from the original dataframe.
            *
            * @return Returns a new dataframe with only the initial sequential rows that were taken while the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.takeWhile(row => row.CustomerName === "Fred"); // Take only initial customers named Fred.
            * </pre>
            */
        takeWhile(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Takes rows from the dataframe untils a condition evaluates to true or truthy.
            *
            * @param predicate Return true/truthy to stop taking rows in the original dataframe.
            *
            * @return Returns a new dataframe with only the initial sequential rows taken until the predicate returned true/truthy.
            *
            * @example
            * <pre>
            *
            * const dfWithRowsTaken = df.takeUntil(row => row.CustomerName === "Fred"); // Take all initial customers until we find Fred.
            * </pre>
            */
        takeUntil(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Count the number of rows in the dataframe
            *
            * @return Returns the count of all rows.
            *
            * @example
            * <pre>
            *
            * const numRows = df.count();
            * </pre>
            */
        count(): number;
        /**
            * Get the first row of the dataframe.
            *
            * @return Returns the first row of the dataframe.
            *
            * @example
            * <pre>
            *
            * const firstRow = df.first();
            * </pre>
            */
        first(): ValueT;
        /**
            * Get the last row of the dataframe.
            *
            * @return Returns the last row of the dataframe.
            *
            * @example
            * <pre>
            *
            * const lastRow = df.last();
            * </pre>
            */
        last(): ValueT;
        /**
            * Get the row, if there is one, with the specified index.
            *
            * @param index Index to for which to retreive the row.
            *
            * @return Returns the row from the specified index in the dataframe or undefined if there is no such index in the present in the dataframe.
            *
            * @example
            * <pre>
            *
            * const row = df.at(5); // Get the row at index 5 (with a default 0-based index).
            * </pre>
            *
            * @example
            * <pre>
            *
            * const date = ... some date ...
            * // Retreive the row with specified date from a time-series dataframe (assuming date indexed has been applied).
            * const row = df.at(date);
            * </pre>
            */
        at(index: IndexT): ValueT | undefined;
        /**
            * Get X rows from the start of the dataframe.
            * Pass in a negative value to get all rows at the head except for X rows at the tail.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe that has only the specified number of rows taken from the start of the original dataframe.
            *
            * @examples
            * <pre>
            *
            * const sample = df.head(10); // Take a sample of 10 rows from the start of the dataframe.
            * </pre>
            */
        head(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Get X rows from the end of the dataframe.
            * Pass in a negative value to get all rows at the tail except X rows at the head.
            *
            * @param numValues Number of rows to take.
            *
            * @return Returns a new dataframe that has only the specified number of rows taken from the end of the original dataframe.
            *
            * @examples
            * <pre>
            *
            * const sample = df.tail(12); // Take a sample of 12 rows from the end of the dataframe.
            * </pre>
            */
        tail(numValues: number): IDataFrame<IndexT, ValueT>;
        /**
            * Filter the dataframe using user-defined predicate function.
            *
            * @param predicate Predicte function to filter rows from the dataframe. Returns true/truthy to keep rows, or false/falsy to omit rows.
            *
            * @return Returns a new dataframe containing only the rows from the original dataframe that matched the predicate.
            *
            * @example
            * <pre>
            *
            * const filteredDf = df.where(row => row.CustomerName === "Fred"); // Filter so we only have customers named Fred.
            * </pre>
            */
        where(predicate: PredicateFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Invoke a callback function for each row in the dataframe.
            *
            * @param callback The calback function to invoke for each row.
            *
            * @return Returns the original dataframe with no modifications.
            *
            * @example
            * <pre>
            *
            * df.forEach(row => {
            *      // ... do something with the row ...
            * });
            * </pre>
            */
        forEach(callback: CallbackFn<ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **all** rows in the dataframe.
            *
            * @param predicate Predicate function that receives each row. It should returns true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned true or truthy for every row in the dataframe, otherwise returns false. Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const everyoneIsNamedFred = df.all(row => row.CustomerName === "Fred"); // Check if all customers are named Fred.
            * </pre>
            */
        all(predicate: PredicateFn<ValueT>): boolean;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **any** of rows in the dataframe.
            *
            * If no predicate is specified then it simply checks if the dataframe contains more than zero rows.
            *
            * @param [predicate] Optional predicate function that receives each row. It should return true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned truthy for any row in the dataframe, otherwise returns false.
            * If no predicate is passed it returns true if the dataframe contains any rows at all.
            * Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const anyFreds = df.any(row => row.CustomerName === "Fred"); // Do we have any customers named Fred?
            * </pre>
            *
            * @example
            * <pre>
            *
            * const anyCustomers = df.any(); // Do we have any customers at all?
            * </pre>
            */
        any(predicate?: PredicateFn<ValueT>): boolean;
        /**
            * Evaluates a predicate function for every row in the dataframe to determine
            * if some condition is true/truthy for **none** of rows in the dataframe.
            *
            * If no predicate is specified then it simply checks if the dataframe contains zero rows.
            *
            * @param [predicate] Optional predicate function that receives each row. It should return true/truthy for a match, otherwise false/falsy.
            *
            * @return Returns true if the predicate has returned truthy for zero rows in the dataframe, otherwise returns false. Returns false for an empty dataframe.
            *
            * @example
            * <pre>
            *
            * const noFreds = df.none(row => row.CustomerName === "Fred"); // Do we have zero customers named Fred?
            * </pre>
            *
            * @example
            * <pre>
            *
            * const noCustomers = df.none(); // Do we have zero customers?
            * </pre>
            */
        none(predicate?: PredicateFn<ValueT>): boolean;
        /**
            * Gets a new dataframe containing all rows starting at or after the specified index value.
            *
            * @param indexValue The index value at which to start the new dataframe.
            *
            * @return Returns a new dataframe containing all rows starting at or after the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3], // This is the default index.
            *      values: [10, 20, 30, 40],
            * });
            *
            * const lastHalf = df.startAt(2);
            * expect(lastHalf.toArray()).to.eql([30, 40]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows starting at (or after) a particular date.
            * const result = timeSeriesDf.startAt(new Date(2016, 5, 4));
            * </pre>
            */
        startAt(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows up until and including the specified index value (inclusive).
            *
            * @param indexValue The index value at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all rows up until and including the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3], // This is the default index.
            *      values: [10, 20, 30, 40],
            * });
            *
            * const firstHalf = df.endAt(1);
            * expect(firstHalf.toArray()).to.eql([10, 20]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows ending at a particular date.
            * const result = timeSeriesDf.endAt(new Date(2016, 5, 4));
            * </pre>
            */
        endAt(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows up to the specified index value (exclusive).
            *
            * @param indexValue The index value at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all rows up to (but not including) the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3], // This is the default index.
            *      values: [10, 20, 30, 40],
            * });
            *
            * const firstHalf = df.before(2);
            * expect(firstHalf.toArray()).to.eql([10, 20]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows before the specified date.
            * const result = timeSeriesDf.before(new Date(2016, 5, 4));
            * </pre>
            */
        before(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows after the specified index value (exclusive).
            *
            * @param indexValue The index value after which to start the new dataframe.
            *
            * @return Returns a new dataframe containing all rows after the specified index value.
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      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 timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows after the specified date.
            * const result = timeSeriesDf.after(new Date(2016, 5, 4));
            * </pre>
            */
        after(indexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe containing all rows between the specified index values (inclusive).
            *
            * @param startIndexValue The index at which to start the new dataframe.
            * @param endIndexValue The index at which to end the new dataframe.
            *
            * @return Returns a new dataframe containing all values between the specified index values (inclusive).
            *
            * @example
            * <pre>
            *
            * const df = new DataFrame({
            *      index: [0, 1, 2, 3, 4, 6], // This is the default index.
            *      values: [10, 20, 30, 40, 50, 60],
            * });
            *
            * const middleSection = df.between(1, 4);
            * expect(middleSection.toArray()).to.eql([20, 30, 40, 50]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const timeSeriesDf = ... a dataframe indexed by date/time ...
            *
            * // Get all rows between the start and end dates (inclusive).
            * const result = timeSeriesDf.after(new Date(2016, 5, 4), new Date(2016, 5, 22));
            * </pre>
            */
        between(startIndexValue: IndexT, endIndexValue: IndexT): IDataFrame<IndexT, ValueT>;
        /**
            * Format the dataframe for display as a string.
            * This forces lazy evaluation to complete.
            *
            * @return Generates and returns a string representation of the dataframe.
            *
            * @example
            * <pre>
            *
            * console.log(df.toString());
            * </pre>
            */
        toString(): string;
        /**
            * Parse a column with string values and convert it to a column with int values.
            *
            * @param columnNameOrNames Specifies the column name or array of column names to parse.
            *
            * @return Returns a new dataframe with values of particular named column(s) parsed from strings to ints.
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseInts("MyIntColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseInts(["MyIntColumnA", "MyIntColumnA"]);
            * </pre>
            */
        parseInts(columnNameOrNames: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Parse a column with string values and convert it to a column with float values.
            *
            * @param columnNameOrNames Specifies the column name or array of column names to parse.
            *
            * @return Returns a new dataframe with values of particular named column(s) parsed from strings to floats.
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseFloats("MyFloatColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseFloats(["MyFloatColumnA", "MyFloatColumnA"]);
            * </pre>
            */
        parseFloats(columnNameOrNames: string | string[]): IDataFrame<IndexT, ValueT>;
        /**
            * Parse a column with string values and convert it to a column with date values.
            *
            * @param columnNameOrNames Specifies the column name or array of column names to parse.
            * @param [formatString] Optional formatting string for dates.
            *
            * Moment is used for date parsing.
            * https://momentjs.com
            *
            * @return Returns a new dataframe with values of particular named column(s) parsed from strings to dates.
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseDates("MyDateColumn");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const parsed = df.parseDates(["MyDateColumnA", "MyDateColumnA"]);
            * </pre>
            */
        parseDates(columnNameOrNames: string | string[], formatString?: string): IDataFrame<IndexT, ValueT>;
        /**
            * Convert a column of values of different types to a column of string values.
            *
            * @param columnNames Specifies the column name or array of column names to convert to strings. Can also be a format spec that specifies which columns to convert and what their format should be.
            * @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 dataframe with a particular named column converted from values to strings.
            *
            * @example
            * <pre>
            *
            * const result = df.toStrings("MyDateColumn", "YYYY-MM-DD");
            * </pre>
            *
            * @example
            * <pre>
            *
            * const result = df.toStrings("MyFloatColumn", "0.00");
            * </pre>
            */
        toStrings(columnNames: string | string[] | IFormatSpec, formatString?: string): IDataFrame<IndexT, ValueT>;
        /**
            * Produces a new dataframe with all string values truncated to the requested maximum length.
            *
            * @param maxLength The maximum length of the string values after truncation.
            *
            * @return Returns a new dataframe with all strings truncated to the specified maximum length.
            *
            * @example
            * <pre>
            *
            * // Truncate all string columns to 100 characters maximum.
            * const truncatedDf = df.truncateString(100);
            * </pre>
            */
        truncateStrings(maxLength: number): IDataFrame<IndexT, ValueT>;
        /**
            * Forces lazy evaluation to complete and 'bakes' the dataframe into memory.
            *
            * @return Returns a dataframe that has been 'baked', all lazy evaluation has completed.
            *
            * @example
            * <pre>
            *
            * const baked = df.bake();
            * </pre>
            */
        bake(): IDataFrame<IndexT, ValueT>;
        /**
            * Gets a new dataframe in reverse order.
            *
            * @return Returns a new dataframe that is the reverse of the input.
            *
            * @example
            * <pre>
            *
            * const reversedDf = df.reverse();
            * </pre>
            */
        reverse(): IDataFrame<IndexT, ValueT>;
        /**
            * Returns only the set of rows in the dataframe that are distinct according to some criteria.
            * This can be used to remove duplicate rows from the dataframe.
            *
            * @param selector User-defined selector function that specifies the criteria used to make comparisons for duplicate rows.
            *
            * @return Returns a dataframe containing only unique values as determined by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Remove duplicate rows by customer id. Will return only a single row per customer.
            * const distinctCustomers = salesDf.distinct(sale => sale.CustomerId);
            * </pre>
            */
        distinct<ToT>(selector?: SelectorFn<ValueT, ToT>): IDataFrame<IndexT, ValueT>;
        /**
            * Collects rows in the dataframe into a series of groups according to the user-defined selector function that defines the group for each row.
            *
            * @param selector User-defined selector function that defines the value to group by.
            *
            * @return Returns a {@link Series} of groups. Each group is a dataframe with values that have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * const salesDf = ... product sales ...
            * const salesByProduct = salesDf.groupBy(sale => sale.ProductId);
            * for (const productSalesGroup of salesByProduct) {
            *      // ... do something with each product group ...
            *      const productId = productSalesGroup.first().ProductId;
            *      const totalSalesForProduct = productSalesGroup.deflate(sale => sale.Amount).sum();
            *      console.log(totalSalesForProduct);
            * }
            * </pre>
            */
        groupBy<GroupT>(selector: SelectorWithIndexFn<ValueT, GroupT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Collects rows in the dataframe into a series of groups according to a user-defined selector function that identifies adjacent rows that should be in the same group.
            *
            * @param selector Optional selector that defines the value to group by.
            *
            * @return Returns a {@link Series} of groups. Each group is a dataframe with values that have been grouped by the 'selector' function.
            *
            * @example
            * <pre>
            *
            * // Some ultra simple stock trading strategy backtesting...
            * const dailyStockPriceDf = ... daily stock price for a company ...
            * const priceGroups  = dailyStockPriceDf.groupBy(day => day.close > day.movingAverage);
            * for (const priceGroup of priceGroups) {
            *      // ... do something with each stock price group ...
            *
            *      const firstDay = priceGroup.first();
            *      if (firstDay.close > movingAverage) {
            *          // This group of days has the stock price above its moving average.
            *          // ... maybe enter a long trade here ...
            *      }
            *      else {
            *          // This group of days has the stock price below its moving average.
            *          // ... maybe enter a short trade here ...
            *      }
            * }
            * </pre>
            */
        groupSequentialBy<GroupT>(selector?: SelectorFn<ValueT, GroupT>): ISeries<number, IDataFrame<IndexT, ValueT>>;
        /**
            * Concatenate multiple dataframes into a single dataframe.
            *
            * @param dataframes Array of dataframes to concatenate.
            *
            * @return Returns a single dataframe concatenated from multiple input dataframes.
            *
            * @example
            * <pre>
            *
            * const df1 = ...
            * const df2 = ...
            * const df3 = ...
            * const concatenatedDf = DataFrame.concat([df1, df2, df3]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const dfs = [... array of dataframes...];
            * const concatenatedDf = DataFrame.concat(dfs);
            * </pre>
            */
        static concat<IndexT = any, ValueT = any>(dataframes: IDataFrame<IndexT, ValueT>[]): IDataFrame<IndexT, ValueT>;
        /**
            * Concatenate multiple other dataframes onto this dataframe.
            *
            * @param dataframes Multiple arguments. Each can be either a dataframe or an array of dataframes.
            *
            * @return Returns a single dataframes concatenated from multiple input dataframes.
            *
            * @example
            * <pre>
            *
            * const concatenatedDf = dfA.concat(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenatedDf = dfA.concat(dfB, dfC);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenatedDf = dfA.concat([dfB, dfC]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const concatenatedDf = dfA.concat(dfB, [dfC, dfD]);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const otherDfs = [... array of dataframes...];
            * const concatenatedDf = dfA.concat(otherDfs);
            * </pre>
            */
        concat(...dataframes: (IDataFrame<IndexT, ValueT>[] | IDataFrame<IndexT, ValueT>)[]): IDataFrame<IndexT, ValueT>;
        /**
         * Zip (or merge) together multiple dataframes to create a new dataframe.
         * Preserves the index of the first dataframe.
         *
         * @param input An iterable of datafames to be zipped.
         * @param zipper User-defined zipper function that merges rows. It produces rows for the new dataframe based-on rows from the input dataframes.
         *
         * @return Returns a single dataframe zipped (or merged) from multiple input dataframes.
         *
         * @example
         * <pre>
         *
         * function produceNewRow (inputRows) {
         *       const outputRow = {
         *           // Produce output row based on the contents of the input rows.
         *       };
         *       return outputRow;
         * }
         *
         * const inputDfs = [... array of input dataframes ...];
         * const zippedDf = DataFrame.zip(inputDfs, produceNewRow);
         *
         * </pre>
         *
         * @example
         * <pre>
         *
         * function produceNewRow (inputRows) {
         *       const outputRow = {
         *           // Produce output row based on the contents of the input rows.
         *       };
         *       return outputRow;
         * }
         *
         * const dfA = new DataFrame([ { Value: 10 }, { Value: 20 }, { Value: 30 }]);
         * const dfB = new DataFrame([ { Value: 100 }, { Value: 200 }, { Value: 300 }]);
         * const zippedDf = DataFrame.zip([dfA, dfB], produceNewRow);
         * </pre>
         */
        static zip<IndexT = any, ValueT = any, ResultT = any>(dataframes: Iterable<IDataFrame<IndexT, ValueT>>, zipper: ZipNFn<ValueT, ResultT>): IDataFrame<IndexT, ResultT>;
        /**
         * Zip (or merge) together multiple dataframes to create a new dataframe.
         * Preserves the index of the first dataframe.
         *
         * @param s2, s3, s4, s4 Multiple dataframes to zip.
         * @param zipper User-defined zipper function that merges rows. It produces rows for the new dataframe based-on rows from the input dataframes.
         *
         * @return Returns a single dataframe zipped (or merged) from multiple input dataframes.
         *
         * @example
         * <pre>
         *
         * function produceNewRow (rowA, rowB) {
         *       const outputRow = {
         *           ValueA: rowA.Value,
         *           ValueB: rowB.Value,
         *       };
         *       return outputRow;
         * }
         *
         * const dfA = new DataFrame([ { Value: 10 }, { Value: 20 }, { Value: 30 }]);
         * const dfB = new DataFrame([ { Value: 100 }, { Value: 200 }, { Value: 300 }]);
         * const zippedDf = dfA.zip(dfB, produceNewRow);
         * </pre>
         */
        zip<Index2T, Value2T, ResultT>(s2: IDataFrame<Index2T, Value2T>, zipper: Zip2Fn<ValueT, Value2T, ResultT>): IDataFrame<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, ResultT>(s2: IDataFrame<Index2T, Value2T>, s3: IDataFrame<Index3T, Value3T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): IDataFrame<IndexT, ResultT>;
        zip<Index2T, Value2T, Index3T, Value3T, Index4T, Value4T, ResultT>(s2: IDataFrame<Index2T, Value2T>, s3: IDataFrame<Index3T, Value3T>, s4: IDataFrame<Index4T, Value4T>, zipper: Zip3Fn<ValueT, Value2T, Value3T, ResultT>): IDataFrame<IndexT, ResultT>;
        /**
            * Sorts the dataframe in ascending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new dataframe that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by amount from least to most.
            * const orderedDf = salesDf.orderBy(sale => sale.Amount);
            * </pre>
            */
        orderBy<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
        /**
            * Sorts the dataframe in descending order by a value defined by the user-defined selector function.
            *
            * @param selector User-defined selector function that selects the value to sort by.
            *
            * @return Returns a new dataframe that has been ordered accorrding to the value chosen by the selector function.
            *
            * @example
            * <pre>
            *
            * // Order sales by amount from most to least
            * const orderedDf = salesDf.orderByDescending(sale => sale.Amount);
            * </pre>
            */
        orderByDescending<SortT>(selector: SelectorWithIndexFn<ValueT, SortT>): IOrderedDataFrame<IndexT, ValueT, SortT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains the union of rows from the two input dataframes.
            * These are the unique combination of rows in both dataframe.
            * This is basically a concatenation and then elimination of duplicates.
            *
            * @param other The other dataframes to merge.
            * @param [selector] Optional user-defined selector function that selects the value to compare to detemrine distinctness.
            *
            * @return Returns the union of the two dataframes.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const merged = dfA.union(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records that may contain the same
            * // customer record in each set. This is basically a concatenation
            * // of the dataframes and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA.union(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            *
            *
            * @example
            * <pre>
            *
            * // Note that you can achieve the exact same result as the previous
            * // example by doing a {@link DataFrame.concat) and {@link DataFrame.distinct}
            * // of the dataframes and then an elimination of any duplicate records
            * // that result.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const mergedCustomerRecords = customerRecordsA
            *      .concat(customerRecordsB)
            *      .distinct(customerRecord => customerRecord.CustomerId);
            * </pre>
            *
            */
        union<KeyT = ValueT>(other: IDataFrame<IndexT, ValueT>, selector?: SelectorFn<ValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains the intersection of rows from the two input dataframes.
            * These are only the rows that appear in both dataframes.
            *
            * @param inner The inner dataframe to merge (the dataframe you call the function on is the 'outer' dataframe).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer dataframe that is used to match the two dataframes.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner dataframe that is used to match the two dataframes.
            *
            * @return Returns a new dataframe that contains the intersection of rows from the two input dataframes.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const mergedDf = dfA.intersection(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Merge two sets of customer records to find only the
            * // customers that appears in both.
            * const customerRecordsA = ...
            * const customerRecordsB = ...
            * const intersectionOfCustomerRecords = customerRecordsA.intersection(
            *      customerRecordsB,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            * */
        intersection<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only the rows from the 1st dataframe that don't appear in the 2nd dataframe.
            * This is essentially subtracting the rows from the 2nd dataframe from the 1st and creating a new dataframe with the remaining rows.
            *
            * @param inner The inner dataframe to merge (the dataframe you call the function on is the 'outer' dataframe).
            * @param [outerSelector] Optional user-defined selector function that selects the key from the outer dataframe that is used to match the two dataframes.
            * @param [innerSelector] Optional user-defined selector function that selects the key from the inner dataframe that is used to match the two dataframes.
            *
            * @return Returns a new dataframe that contains only the rows from the 1st dataframe that don't appear in the 2nd dataframe.
            *
            * @example
            * <pre>
            *
            * const dfA = ...
            * const dfB = ...
            * const remainingDf = dfA.except(dfB);
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Find the list of customers haven't bought anything recently.
            * const allCustomers = ... list of all customers ...
            * const recentCustomers = ... list of customers who have purchased recently ...
            * const remainingCustomers = allCustomers.except(
            *      recentCustomers,
            *      customerRecord => customerRecord.CustomerId
            * );
            * </pre>
            */
        except<InnerIndexT = IndexT, InnerValueT = ValueT, KeyT = ValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerSelector?: SelectorFn<ValueT, KeyT>, innerSelector?: SelectorFn<InnerValueT, KeyT>): IDataFrame<IndexT, ValueT>;
        /**
             * Creates a new dataframe by merging two input dataframes.
             * The resulting dataframe contains only those rows that have matching keys in both input dataframes.
             *
             * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
             * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
             * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
             * @param resultSelector User-defined function that merges outer and inner values.
             *
             * @return Returns the new merged dataframe.
             *
             * @example
             * <pre>
             *
             * // Join together two sets of customers to find those
             * // that have bought both product A and product B.
             * const customerWhoBoughtProductA = ...
             * const customerWhoBoughtProductB = ...
             * const customersWhoBoughtBothProductsDf = customerWhoBoughtProductA.join(
             *          customerWhoBoughtProductB,
             *          customerA => customerA.CustomerId, // Join key.
             *          customerB => customerB.CustomerId, // Join key.
             *          (customerA, customerB) => {
             *              return {
             *                  // ... merge the results ...
             *              };
             *          }
             *      );
             * </pre>
             */
        join<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT, InnerValueT, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that are only present in or or the other of the dataframes, not both.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either product A or product B, not not both.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const customersWhoBoughtEitherProductButNotBothDf = customerWhoBoughtProductA.joinOuter(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuter<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that present either in both dataframes or only in the outer (left) dataframe.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product A or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterLeft(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterLeft<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Creates a new dataframe by merging two input dataframes.
            * The resulting dataframe contains only those rows that present either in both dataframes or only in the inner (right) dataframe.
            *
            * @param inner The 'inner' dataframe to join (the dataframe you are callling the function on is the 'outer' dataframe).
            * @param outerKeySelector User-defined selector function that chooses the join key from the outer dataframe.
            * @param innerKeySelector User-defined selector function that chooses the join key from the inner dataframe.
            * @param resultSelector User-defined function that merges outer and inner values.
            *
            * Implementation from here:
            *
            * 	http://blogs.geniuscode.net/RyanDHatch/?p=116
            *
            * @return Returns the new merged dataframe.
            *
            * @example
            * <pre>
            *
            * // Join together two sets of customers to find those
            * // that have bought either just product B or both product A and product B.
            * const customerWhoBoughtProductA = ...
            * const customerWhoBoughtProductB = ...
            * const boughtJustAorAandB = customerWhoBoughtProductA.joinOuterRight(
            *          customerWhoBoughtProductB,
            *          customerA => customerA.CustomerId, // Join key.
            *          customerB => customerB.CustomerId, // Join key.
            *          (customerA, customerB) => {
            *              return {
            *                  // ... merge the results ...
            *              };
            *          }
            *      );
            * </pre>
            */
        joinOuterRight<KeyT, InnerIndexT, InnerValueT, ResultValueT>(inner: IDataFrame<InnerIndexT, InnerValueT>, outerKeySelector: SelectorFn<ValueT, KeyT>, innerKeySelector: SelectorFn<InnerValueT, KeyT>, resultSelector: JoinFn<ValueT | null, InnerValueT | null, ResultValueT>): IDataFrame<number, ResultValueT>;
        /**
            * Produces a summary of dataframe. A bit like the 'aggregate' function but much simpler.
            *
            * @param [spec] Optional parameter that specifies which columns to aggregate and how to aggregate them. Leave this out to produce a default summary of all columns.
            *
            * @returns A object with fields that summary the values in the dataframe.
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize();
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Summarize using pre-defined functions.
            *      Column1: Series.sum,
            *      Column2: Series.average,
            *      Column3: Series.count,
            * });
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Summarize using custom functions.
            *      Column1: series => series.sum(),
            *      Column2: series => series.std(),
            *      ColumnN: whateverFunctionYouWant,
            * });
            * console.log(summary);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const summary = df.summarize({ // Multiple output fields per column.
            *      Column1: {
            *          OutputField1: Series.sum,
            *          OutputField2: Series.average,
            *      },
            *      Column2: {
            *          OutputField3: series => series.sum(),
            *          OutputFieldN: whateverFunctionYouWant,
            *      },
            * });
            * console.log(summary);
            * </pre>
            */
        summarize<OutputValueT = any>(spec?: IMultiColumnAggregatorSpec): OutputValueT;
        /**
            * Reshape (or pivot) a dataframe based on column values.
            * This is a powerful function that combines grouping, aggregation and sorting.
            *
            * @param columnOrColumns Column name whose values make the new DataFrame's columns.
            * @param valueColumnNameOrSpec Column name or column spec that defines the columns whose values should be aggregated.
            * @param [aggregator] Optional function used to aggregate pivotted vales.
            *
            * @return Returns a new dataframe that has been pivoted based on a particular column's values.
            *
            * @example
            * <pre>
            *
            * // Simplest example.
            * // Group by the values in 'PivotColumn'.
            * // The unique set of values in 'PivotColumn' becomes the columns in the resulting dataframe.
            * // The column 'ValueColumn' is aggregated for each group and this becomes the
            * // values in the new output column.
            * const pivottedDf = df.pivot("PivotColumn", "ValueColumn", values => values.average());
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Multiple input column example.
            * // Similar to the previous example except now we are aggregating multiple input columns.
            * // Each group has the average computed for 'ValueColumnA' and the sum for 'ValueColumnB'.
            * const pivottedDf = df.pivot("PivotColumn", {
            *      ValueColumnA: aValues => aValues.average(),
            *      ValueColumnB:  bValues => bValues.sum(),
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Multiple output column example.
            * // Similar to the previous example except now we are doing multiple aggregations for each input column.
            * // The example produces an output dataframe with columns OutputColumnA, B, C and D.
            * // OutputColumnA/B are the sum and average of ValueColumnA across each group as defined by PivotColumn.
            * // OutputColumnC/D are the sum and average of ValueColumnB across each group as defined by PivotColumn.
            * const pivottedDf = df.pivot("PivotColumn", {
            *      ValueColumnA: {
            *          OutputColumnA: aValues => aValues.sum(),
            *          OutputColumnB: aValues => aValues.average(),
            *      },
            *      ValueColumnB: {
            *          OutputColumnC: bValues => aValues.sum(),
            *          OutputColumnD: bValues => aValues.average(),
            *      },
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // Full multi-column example.
            * // Similar to the previous example now we are pivotting on multiple columns.
            * // We now group by the 'PivotColumnA' and then by 'PivotColumnB', effectively creating a
            * // multi-level group.
            * const pivottedDf = df.pivot(["PivotColumnA", "PivotColumnB" ], {
            *      ValueColumnA: aValues => aValues.average(),
            *      ValueColumnB:  bValues => bValues.sum(),
            * });
            * </pre>
            *
            * @example
            * <pre>
            *
            * // To help understand the pivot function, let's look at what it does internally.
            * // Take the simplest example:
            * const pivottedDf = df.pivot("PivotColumn", "ValueColumn", values => values.average());
            *
            * // If we expand out the internals of the pivot function, it will look something like this:
            * const pivottedDf = df.groupBy(row => row.PivotColumn)
            *          .select(group => ({
            *              PivotColumn: group.deflate(row.ValueColumn).average()
            *          }))
            *          .orderBy(row  => row.PivotColumn);
            *
            * // You can see that pivoting a dataframe is the same as grouping, aggregating and sorting it.
            * // Does pivoting seem simpler now?
            *
            * // It gets more complicated than that of course, because the pivot function supports multi-level nested
            * // grouping and aggregation of multiple columns. So a full expansion of the pivot function is rather complex.
            * </pre>
            */
        pivot<NewValueT = ValueT>(columnOrColumns: string | Iterable<string>, valueColumnNameOrSpec: string | IMultiColumnAggregatorSpec, aggregator?: (values: ISeries<number, any>) => any): IDataFrame<number, NewValueT>;
        /**
            * Insert a pair at the start of the dataframe.
            * Doesn't modify the original dataframe! The returned dataframe is entirely new and contains rows from the original dataframe plus the inserted pair.
            *
            * @param pair The pair to insert.
            *
            * @return Returns a new dataframe with the specified pair inserted.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to insert ...
            * const insertedDf = df.insertPair([newIndex, newRows]);
            * </pre>
            */
        insertPair(pair: [IndexT, ValueT]): IDataFrame<IndexT, ValueT>;
        /**
            * Append a pair to the end of a dataframe.
            * Doesn't modify the original dataframe! The returned dataframe is entirely new and contains rows from the original dataframe plus the appended pair.
            *
            * @param pair - The pair to append.
            *
            * @return Returns a new dataframe with the specified pair appended.
            *
            * @example
            * <pre>
            *
            * const newIndex = ... index of the new row ...
            * const newRow = ... the new data row to append ...
            * const appendedDf = df.appendPair([newIndex, newRows]);
            * </pre>
            */
        appendPair(pair: [IndexT, ValueT]): IDataFrame<IndexT, ValueT>;
        /**
            * Fill gaps in a dataframe.
            *
            * @param comparer User-defined comparer function that is passed pairA and pairB, two consecutive rows, return truthy if there is a gap between the rows, or falsey if there is no gap.
            * @param generator User-defined generator function that is passed pairA and pairB, two consecutive rows, returns an array of pairs that fills the gap between the rows.
            *
            * @return Returns a new dataframe with gaps filled in.
            *
            * @example
            * <pre>
            *
            *   var sequenceWithGaps = ...
            *
            *  // Predicate that determines if there is a gap.
            *  var gapExists = (pairA, pairB) => {
            *      // Returns true if there is a gap.
            *      return true;
            *  };
            *
            *  // Generator function that produces new rows to fill the game.
            *  var gapFiller = (pairA, pairB) => {
            *      // Create an array of index, value pairs that fill the gaps between pairA and pairB.
            *      return [
            *          newPair1,
            *          newPair2,
            *          newPair3,
            *      ];
            *  };
            *
            *  var sequenceWithoutGaps = sequenceWithGaps.fillGaps(gapExists, gapFiller);
            * </pre>
            */
        fillGaps(comparer: ComparerFn<[IndexT, ValueT], [IndexT, ValueT]>, generator: GapFillFn<[IndexT, ValueT], [IndexT, ValueT]>): IDataFrame<IndexT, ValueT>;
        /**
            * Returns the specified default dataframe if the dataframe is empty.
            *
            * @param defaultDataFrame Default dataframe to return if the dataframe is empty.
            *
            * @return Returns 'defaultDataFrame' if the dataframe is empty.
            *
            * @example
            * <pre>
            *
            * const emptyDataFrame = new DataFrame();
            * const defaultDataFrame = new DataFrame([ { A: 1 }, { A: 2 }, { A: 3 } ]);
            * expect(emptyDataFrame.defaultIfEmpty(defaultDataFrame)).to.eql(defaultDataFrame);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const nonEmptyDataFrame = new DataFrame([ { A: 100 }]);
            * const defaultDataFrame = new DataFrame([ { A: 1 }, { A: 2 }, { A: 3 } ]);
            * expect(nonEmptyDataFrame.defaultIfEmpty(defaultDataFrame)).to.eql(nonEmptyDataFrame);
            * </pre>
            */
        defaultIfEmpty(defaultDataFrame: ValueT[] | IDataFrame<IndexT, ValueT>): IDataFrame<IndexT, ValueT>;
        /**
            * Detect the the frequency of the types of the values in the dataframe.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a dataframe with rows that confirm to {@link ITypeFrequency} that describes the data types contained in the original dataframe.
            *
            * @example
            * <pre>
            *
            * const df = dataForge.readFileSync("./my-data.json").parseJSON();
            * const dataTypes = df.detectTypes();
            * console.log(dataTypes.toString());
            * </pre>
            */
        detectTypes(): IDataFrame<number, ITypeFrequency>;
        /**
            * Detect the frequency of the values in the dataframe.
            * This is a good way to understand the shape of your data.
            *
            * @return Returns a dataframe with rows that conform to {@link IValueFrequency} that describes the values contained in the dataframe.
            *
            * @example
            * <pre>
            *
            * const df = dataForge.readFileSync("./my-data.json").parseJSON();
            * const dataValues = df.detectedValues();
            * console.log(dataValues.toString());
            * </pre>
            */
        detectValues(): IDataFrame<number, IValueFrequency>;
        /**
            * Serialize the dataframe to the JSON data format.
            *
            * @return Returns a string in the JSON data format that represents the dataframe.
            *
            * @example
            * <pre>
            *
            * const jsonData = df.toJSON();
            * console.log(jsonData);
            * </pre>
            */
        toJSON(): string;
        /**
            * Serialize the dataframe to the CSV data format.
            *
            * @return Returns a string in the CSV data format that represents the dataframe.
            *
            * @example
            * <pre>
            *
            * const csvData = df.toCSV();
            * console.log(csvData);
            * </pre>
            *
            * @example
            * <pre>
            *
            * const csvData = df.toCSV({ header: false });
            * console.log(csvData);
            * </pre>
            */
        toCSV(options?: ICSVOutputOptions): string;
        /**
            * Serialize the dataframe to HTML.
            *
            * @return Returns a string in HTML format that represents the dataframe.
            */
        toHTML(): string;
        /**
            * Serialize the dataframe to an ordinary JavaScript data structure.
            * The resulting data structure is suitable for further serialization to JSON and can be used to
            * transmit a DataFrame and its internal structure over the wire.
            * Use the {@link deserialize} function to later reconstitute the serialized dataframe.
            *
            * @return Returns a JavaScript data structure conforming to {@link ISerializedDataFrame} that represents the dataframe and its internal structure.
            *
            * @example
            * <pre>
            *
            * const jsDataStructure = df.serialize();
            * const jsonData = JSON.stringify(jsDataStructure);
            * console.log(jsonData);
            * const deserializedJsDataStructure = JSON.parse(jsonData);
            * const deserializedDf = DataFrame.deserialize(deserializedJsDataStructure); // Reconsituted.
            * </pre>
            */
        serialize(): ISerializedDataFrame;
        /**
            * Deserialize the dataframe from an ordinary JavaScript data structure.
            * Can reconstitute a dataframe that previously serialized with the {@link serialize} function.
            * This can rebuilds the dataframe with the exact same internal structure after it has been transmitted over the wire.
            *
            * @param input The serialize JavaScript data structure for the dataframe.
            *
            * @return Returns the deserialized/reconstituted dataframe.
            *
            * @example
            * <pre>
            *
            * const jsDataStructure = df.serialize();
            * const jsonData = JSON.stringify(jsDataStructure);
            * console.log(jsonData);
            * const deserializedJsDataStructure = JSON.parse(jsonData);
            * const deserializedDf = DataFrame.deserialize(deserializedJsDataStructure); // Reconsituted.
            * </pre>
            */
        static deserialize<IndexT = any, ValueT = any>(input: ISerializedDataFrame): IDataFrame<IndexT, ValueT>;
        /***
            * Allows the dataframe to be queried to confirm that it is actually a dataframe.
            * Used from JavaScript to tell the difference between a Series and a DataFrame.
            *
            * @return Returns the string "dataframe".
            */
        getTypeCode(): string;
}

export { Index, IIndex } from 'data-forge/--/build/lib/index';
export { Series, ISeries, SelectorWithIndexFn } from 'data-forge/--/build/lib/series';
export { DataFrame, IDataFrame } from 'data-forge/--/build/lib/dataframe';
import { Series, ISeries } from 'data-forge/--/build';
import { DataFrame, IDataFrame } from 'data-forge/--/build';
/**
    * Represents a field from a JavaScript object.
    */
export interface IFieldRecord {
        /**
            * The name of the field.
            */
        Field: string;
        /**
            * The value of the field.
            */
        Value: any;
}
/**
    * Convert a regular JavaScript obejct to a dataframe.
    * Each row in the dataframe represents a field from the object.
    *
    * @param obj - The JavaScript object to convert to a dataframe.
    *
    * @returns Returns a dataframe that lists the fields in the pass-in object.
    */
export declare function fromObject(obj: any): IDataFrame<number, IFieldRecord>;
/**
    * Deserialize a dataframe from a JSON text string.
    *
    * @param jsonTextString The JSON text to deserialize.
    *
    * @returns Returns a dataframe that has been deserialized from the JSON data.
    */
export declare function fromJSON(jsonTextString: string): IDataFrame<number, any>;
/**
    * Options for parsing CSV data.
    */
export interface ICSVOptions {
        /**
            * Optionally specifies the column names (when enabled, assumes that the header row is not read from the CSV data).
            * Default: undefined
            */
        columnNames?: Iterable<string>;
        /**
            * Automatically pick types based on what the value looks like.
            * Default: false.
            */
        dynamicTyping?: boolean;
        /**
            * Skip empty lines in the input.
            * Default: true
            */
        skipEmptyLines?: boolean;
}
/**
    * Deserialize a DataFrame from a CSV text string.
    *
    * @param csvTextString The CSV text to deserialize.
    * @param [config] Optional configuration options for parsing the CSV data.
    *
    * @returns Returns a dataframe that has been deserialized from the CSV data.
    */
export declare function fromCSV(csvTextString: string, config?: ICSVOptions): DataFrame<number, any>;
declare const concat: typeof Series.concat;
/**
    * Concatenate multiple series into a single series.
    * THIS FUNCTION IS DEPRECATED. Instead use dataFrame.Series.concat.
    *
    * @param {array} series - Array of series to concatenate.
    *
    * @returns {Series} - Returns the single concatendated series.
    */
export { concat as concatSeries };
declare const zip: typeof Series.zip;
/**
    * Zip together multiple series to create a new series.
    * THIS FUNCTION IS DEPRECATED. Instead use dataFrame.Series.zip.
    *
    * @param {array} series - Array of series to zip together.
    * @param {function} selector - Selector function that produces a new series based on the input series.
    *
    * @returns {Series} Returns a single series that is the combination of multiple input series that have been 'zipped' together by the 'selector' function.
    */
export { zip as zipSeries };
/**
    * Generate a series from a range of numbers.
    *
    * @param start - The value of the first number in the range.
    * @param count - The number of sequential values in the range.
    *
    * @returns Returns a series with a sequence of generated values. The series contains 'count' values beginning at 'start'.
    */
export declare function range(start: number, count: number): ISeries<number, number>;
/**
    * Replicate a particular value N times to create a series.
    *
    * @param value The value to replicate.
    * @param count The number of times to replicate the value.
    *
    * @returns Returns a new series that contains N copies of the value.
    */
export declare function replicate<ValueT>(value: ValueT, count: number): ISeries<number, ValueT>;
/**
    * Generate a data-frame containing a matrix of values.
    *
    * @param numColumns - The number of columns in the data-frame.
    * @param numRows - The number of rows in the data-frame.
    * @param start - The starting value.
    * @param increment - The value to increment by for each new value.
    *
    * @returns Returns a dataframe that contains a matrix of generated values.
    */
export declare function matrix(numColumns: number, numRows: number, start: number, increment: number): IDataFrame<number, any>;

