import { IIndex } from './index';
import { IDataFrame } from './dataframe';
/**
 * Used to configure a series.
 */
export interface ISeriesConfig<IndexT, ValueT> {
    /**
     * Values to put in the dataframe.
     * This should be array or iterable of JavaScript values.
     */
    values?: 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> {
    private configFn;
    private content;
    private static readonly defaultCountIterable;
    private static readonly defaultEmptyIterable;
    private static initFromArray<IndexT, ValueT>(arr);
    private static initEmpty<IndexT, ValueT>();
    private static checkIterable<T>(input, fieldName);
    private static initFromConfig<IndexT, ValueT>(config);
    /**
     * 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>);
    private lazyInit();
    private getContent();
    /**
     * 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;
}
