Skip to content

deepbox/dataframe

Accessors & Indexing

String, datetime, categorical and multi-level index helpers: Series.str, Series.dt, Categorical, MultiIndex, toDatetime and dateRange.

  • Accessors

Overview

  • series.str and series.dt are accessors on Series. Most str methods use the pandas names (upper, contains, extract, split, zfill), and getDummies replaces get_dummies. Missing values stay missing. str.replace(pattern, replacement, regex = true) treats a string pattern as a regular expression, unlike pandas.
  • Dates are plain JavaScript Date values, and every component is read in local time. There is no time zone support. toDatetime reads date-only and zone-less strings as local time and keeps the exact instant of strings with Z or an offset.
  • dateRange(start, periods, freq) takes a period count, not an end date. The frequencies are D, H, min, S, MS and YS.
  • The dt methods are camelCase (dayOfWeek(), isLeapYear(), dayName()). The lowercase dayofweek, dayofyear, weekofyear and daysinmonth and the snake_case forms are deprecated.
  • Categorical holds values from a fixed list of categories, with optional ordering. MultiIndex builds hierarchical labels with fromArrays, fromTuples and fromProduct.

Types

2

DateFreq

type

Frequencies accepted by date_range: day, hour, minute, second, month start (MS) and year start (YS). Lowercase h and s are pandas' current spellings of H and S.

type DateFreq = "D" | "H" | "h" | "min" | "S" | "s" | "MS" | "YS";

DateRoundFreq

type

Frequencies accepted by floor, ceil and round. Lowercase h and s are pandas' current spellings.

type DateRoundFreq = "D" | "H" | "h" | "min" | "S" | "s";

Classes

4

Categorical

Categorical data type with optional ordering, modeled on pandas.Categorical.

Values are stored as integer codes that index into a category list, so a column with many repeated strings keeps each distinct string only once. Missing values (null or undefined on input) are stored as code -1.

Instances are immutable: every method that changes categories, order or data returns a new Categorical. The codes array is returned without copying for speed and must be treated as read-only.

Ordered categoricals support Categorical.compare, Categorical.min and Categorical.max.

Example
import { Categorical } from 'deepbox/dataframe'; // Unordered categoricalconst colors = Categorical.from(['red', 'blue', 'red', 'green', 'blue']);console.log(colors.categories);  // ['blue', 'green', 'red']console.log(colors.codes);       // Int32Array [2, 0, 2, 1, 0] // Ordered categorical (e.g., size)const sizes = Categorical.from(['M', 'S', 'L', 'M', 'XL'], {  categories: ['S', 'M', 'L', 'XL'],  ordered: true});
Members (25)
  • categories: readonly string[]

    Get the category list

  • codes: Int32Array

    Get the integer codes array (-1 marks a missing value).

  • ordered: boolean

    Whether categories are ordered

  • length: number

    Number of elements

  • nCategories: number

    Number of unique categories (excluding missing)

  • static from(values: ReadonlyArray<string | null | undefined>, options?: { readonly categories?: readonly string[]; readonly ordered?: boolean; }): Categorical

    Create a Categorical from an array of values.

  • get(index: number): string | null

    Get the string value at a given index.

  • toArray(): (string | null)[]

    Convert back to a string array.

  • isNull(): boolean[]

    Boolean mask marking missing values.

  • valueCounts(): Map<string, number>

    Count occurrences of each category.

  • addCategories(newCategories: readonly string[]): Categorical

    Add new categories to the category list.

  • removeCategories(removeCategories: readonly string[]): Categorical

    Remove categories from the category list.

  • removeUnusedCategories(): Categorical

    Remove categories that do not occur in the data.

  • reorderCategories(newOrder: readonly string[], options?: { readonly ordered?: boolean; }): Categorical

    Reorder categories.

  • setCategories(newCategories: readonly string[], options?: { readonly ordered?: boolean; }): Categorical

    Replace the category list.

  • setOrdered(ordered: boolean): Categorical

    Set whether categories are ordered.

  • asOrdered(): Categorical

    Return an ordered copy.

  • asUnordered(): Categorical

    Return an unordered copy.

  • renameCategories(mapping: Readonly<Record<string, string>> | ReadonlyMap<string, string> | ((category: string) => string)): Categorical

    Rename categories.

  • compare(a: string, b: string): number

    Compare two values by their category order (only for ordered categoricals).

  • min(): string | null

    Smallest value by category order.

  • max(): string | null

    Largest value by category order.

  • sort(ascending?: boolean): Categorical

    Sort the values by category order.

  • memoryUsage(): number

    Estimate memory usage in bytes.

  • toString(): string

    Text summary with the first and last values and the category list.

DateTimeAccessor

DateTime accessor for Series, providing vectorized date/time operations.

Accessed via series.dt. Operates element-wise on Series containing Date objects, ISO date strings, or epoch milliseconds. Null, undefined, NaN and empty-string elements propagate as null in the output.

Date-only and zone-less datetime strings are read as local time, and all component getters (year(), hour(), ...) report local time, like pandas' naive datetimes. Strings with an explicit Z or UTC offset denote an exact instant and are shown in local time.

Example
const s = new Series([new Date('2024-01-15'), new Date('2024-06-20')]);s.dt.year();       // Series([2024, 2024])s.dt.month();      // Series([1, 6])s.dt.dayOfWeek();  // Series([0, 3])  (Mon=0 ... Sun=6)
Members (47)
  • constructor(series: Series<unknown>)
  • year(): Series<number | null>

    Calendar year of each date.

  • month(): Series<number | null>

    Month of each date, 1 (January) to 12 (December).

  • day(): Series<number | null>

    Day of the month, 1-31.

  • hour(): Series<number | null>

    Hour of the day, 0-23.

  • minute(): Series<number | null>

    Minute of the hour, 0-59.

  • second(): Series<number | null>

    Second of the minute, 0-59.

  • millisecond(): Series<number | null>

    Millisecond of the second, 0-999.

  • dayOfWeek(): Series<number | null>

    Day of week: Monday=0, Tuesday=1, ..., Sunday=6 (ISO convention).

  • dayofweek(): Series<number | null>deprecated

    Same as DateTimeAccessor.dayOfWeek.

  • weekday(): Series<number | null>

    Alias of DateTimeAccessor.dayOfWeek.

  • dayOfYear(): Series<number | null>

    Day of year: 1-366.

  • dayofyear(): Series<number | null>deprecated

    Same as DateTimeAccessor.dayOfYear.

  • weekOfYear(): Series<number | null>

    ISO 8601 week number (1-53).

  • weekofyear(): Series<number | null>deprecated

    Same as DateTimeAccessor.weekOfYear.

  • week(): Series<number | null>

    Alias of DateTimeAccessor.weekOfYear.

  • quarter(): Series<number | null>

    Quarter: 1-4.

  • isLeapYear(): Series<boolean | null>

    Whether the year is a leap year.

  • is_leap_year(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isLeapYear.

  • daysInMonth(): Series<number | null>

    Days in the month of each date.

  • days_in_month(): Series<number | null>deprecated

    Same as DateTimeAccessor.daysInMonth.

  • daysinmonth(): Series<number | null>deprecated

    Same as DateTimeAccessor.daysInMonth.

  • isMonthStart(): Series<boolean | null>

    Whether each date is the first day of its month.

  • is_month_start(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isMonthStart.

  • isMonthEnd(): Series<boolean | null>

    Whether each date is the last day of its month.

  • is_month_end(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isMonthEnd.

  • isQuarterStart(): Series<boolean | null>

    Whether each date is the first day of a quarter.

  • is_quarter_start(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isQuarterStart.

  • isQuarterEnd(): Series<boolean | null>

    Whether each date is the last day of a quarter.

  • is_quarter_end(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isQuarterEnd.

  • isYearStart(): Series<boolean | null>

    Whether each date is January 1.

  • is_year_start(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isYearStart.

  • isYearEnd(): Series<boolean | null>

    Whether each date is December 31.

  • is_year_end(): Series<boolean | null>deprecated

    Same as DateTimeAccessor.isYearEnd.

  • dayName(): Series<string | null>

    English weekday name of each date ("Monday", ...).

  • day_name(): Series<string | null>deprecated

    Same as DateTimeAccessor.dayName.

  • monthName(): Series<string | null>

    English month name of each date ("January", ...).

  • month_name(): Series<string | null>deprecated

    Same as DateTimeAccessor.monthName.

  • timestamp(): Series<number | null>

    Convert each date to epoch milliseconds (UTC based, independent of the local zone).

  • isoformat(): Series<string | null>

    Convert each date to an ISO 8601 string in UTC, such as "2024-01-01T12:00:00.000Z".

  • strftime(fmt: string): Series<string | null>

    Format each date using a strftime-style pattern, in local time.

  • date(): Series<Date | null>

    Truncate to date only (midnight).

  • normalize(): Series<Date | null>

    Alias of DateTimeAccessor.date, like pandas' normalize().

  • time(): Series<string | null>

    Extract the time portion as "HH:MM:SS".

  • floor(freq: DateRoundFreq): Series<Date | null>

    Floor each date to the start of the given frequency.

  • ceil(freq: DateRoundFreq): Series<Date | null>

    Ceil each date to the next boundary of the given frequency.

  • round(freq: DateRoundFreq): Series<Date | null>

    Round each date to the nearest boundary of the given frequency.

MultiIndex

Hierarchical (multi-level) index for DataFrames.

A MultiIndex represents a composite key made of multiple levels, enabling hierarchical row or column labeling. Each level is a separate array of labels, and the combination of labels across levels uniquely identifies each row.

Example
import { MultiIndex } from 'deepbox/dataframe'; // Create from arraysconst mi = MultiIndex.fromArrays(  [['US', 'US', 'UK', 'UK'], [2020, 2021, 2020, 2021]],  ['country', 'year']);console.log(mi.length);  // 4console.log(mi.nlevels); // 2console.log(mi.get(0));  // ['US', 2020] // Create from tuplesconst mi2 = MultiIndex.fromTuples(  [['US', 2020], ['US', 2021], ['UK', 2020], ['UK', 2021]],  ['country', 'year']);
Members (20)
  • length: number

    Number of entries

  • nlevels: number

    Number of levels

  • names: readonly string[]

    Level names

  • levels: ReadonlyArray<readonly (string | number)[]>

    Label arrays, one per level.

  • isUnique: boolean

    True when no two entries have the same label tuple.

  • static fromArrays(arrays: ReadonlyArray<readonly (string | number)[]>, names?: readonly string[]): MultiIndex

    Create a MultiIndex from separate arrays for each level.

  • static fromTuples(tuples: ReadonlyArray<readonly (string | number)[]>, names?: readonly string[]): MultiIndex

    Create a MultiIndex from an array of tuples.

  • static fromProduct(levels: ReadonlyArray<readonly (string | number)[]>, names?: readonly string[]): MultiIndex

    Create a MultiIndex representing all combinations of the given levels (Cartesian product).

  • get(index: number): (string | number)[]

    Get the label tuple at a given position.

  • toTuples(): (string | number)[][]

    Get all label tuples as arrays.

  • getLevel(level: number | string): readonly (string | number)[]

    Get a specific level's values.

  • getLevelValues(level: number | string): (string | number)[]

    Get unique values at a specific level, in order of first appearance.

  • getPosition(labels: readonly (string | number)[]): number

    Find the position of a given label tuple.

  • has(labels: readonly (string | number)[]): boolean

    Whether a full label tuple is present.

  • equals(other: MultiIndex): boolean

    Whether another MultiIndex has the same names, levels and labels in the same order.

  • select(partialLabels: Readonly<Record<string, string | number>>): number[]

    Select rows matching a partial label specification.

  • droplevel(level: number | string): MultiIndex

    Drop a level from the MultiIndex.

  • swaplevel(i: number | string, j: number | string): MultiIndex

    Swap two levels in the MultiIndex.

  • toFlatIndex(separator?: string): string[]

    Convert to a flat array of stringified tuples for use as DataFrame index.

  • toString(): string

    Describe the index: size, level names and the first five entries.

StringAccessor

String accessor for Series, providing vectorized string operations.

Accessed via series.str. Operates element-wise on string Series. Null/undefined elements propagate as null in the output. Any other non-string element raises a DataValidationError.

Lengths, padding widths and slice positions count Unicode code points (not UTF-16 units), as in pandas, so an emoji counts as one character.

Example
const s = new Series(['hello', 'WORLD', null]);s.str.upper();       // Series(['HELLO', 'WORLD', null])s.str.lower();       // Series(['hello', 'world', null])s.str.contains('lo'); // Series([true, false, null])
Members (43)
  • constructor(series: Series<unknown>)
  • upper(): Series<string | null>

    Convert every string to upper case.

  • lower(): Series<string | null>

    Convert every string to lower case.

  • title(): Series<string | null>

    Capitalize the first letter of every word and lower-case the rest, like Python's str.title().

  • capitalize(): Series<string | null>

    Upper-case the first character and lower-case the rest.

  • swapcase(): Series<string | null>

    Swap the case of every character.

  • strip(chars?: string): Series<string | null>

    Remove characters from both ends.

  • lstrip(chars?: string): Series<string | null>

    Remove characters from the start.

  • rstrip(chars?: string): Series<string | null>

    Remove characters from the end.

  • contains(pat: string | RegExp, regex?: boolean, caseSensitive?: boolean): Series<boolean | null>

    Test whether each string contains a pattern anywhere.

  • startswith(pat: string): Series<boolean | null>

    Test whether each string starts with pat (a literal string).

  • endswith(pat: string): Series<boolean | null>

    Test whether each string ends with pat (a literal string).

  • match(pat: string | RegExp): Series<boolean | null>

    Test whether the pattern matches at the start of each string, like Python's re.match.

  • fullmatch(pat: string | RegExp): Series<boolean | null>

    Test whether the pattern matches each whole string.

  • replace(pat: string | RegExp, repl: string, regex?: boolean): Series<string | null>

    Replace every occurrence of a pattern.

  • split(pat?: string | RegExp, n?: number): Series<string[] | null>

    Split each string into a list of parts.

  • len(): Series<number | null>

    Number of characters (Unicode code points) in each string.

  • slice(start?: number, stop?: number, step?: number): Series<string | null>

    Slice each string with Python semantics (negative positions count from the end).

  • get(position: number): Series<string | null>

    Get the character at a position (negative positions count from the end).

  • extract(pat: string | RegExp, group?: number): Series<string | null>

    Extract one capture group of the first match in each string.

  • findall(pat: string | RegExp): Series<string[] | null>

    Find all non-overlapping matches of a pattern in each string.

  • find(sub: string): Series<number | null>

    Lowest position (in characters) at which sub occurs, or -1 when absent.

  • rfind(sub: string): Series<number | null>

    Highest position (in characters) at which sub occurs, or -1 when absent.

  • removeprefix(prefix: string): Series<string | null>

    Remove prefix from the start of each string when present.

  • removesuffix(suffix: string): Series<string | null>

    Remove suffix from the end of each string when present.

  • pad(width: number, side?: "left" | "right" | "both", fillchar?: string): Series<string | null>

    Pad each string to a minimum width.

  • center(width: number, fillchar?: string): Series<string | null>

    Center each string in a field of the given width.

  • ljust(width: number, fillchar?: string): Series<string | null>

    Left-align each string in a field of the given width, filling on the right.

  • rjust(width: number, fillchar?: string): Series<string | null>

    Right-align each string in a field of the given width, filling on the left.

  • zfill(width: number): Series<string | null>

    Pad each string with zeros on the left to the given width.

  • cat(sep?: string): string

    Join all non-null strings into one string.

  • getDummies(sep?: string): DataFrame

    Split each string on sep and build 0/1 indicator columns, one per distinct token, ordered alphabetically.

  • get_dummies(sep?: string): DataFramedeprecated

    Same as StringAccessor.getDummies.

  • repeat(times: number): Series<string | null>

    Repeat each string times times.

  • count(pat: string | RegExp): Series<number | null>

    Count the non-overlapping matches of a pattern in each string.

  • isalpha(): Series<boolean | null>

    True where every character is a letter (any script) and the string is not empty.

  • isdigit(): Series<boolean | null>

    True where every character is a digit (decimal digits of any script, plus superscript and subscript digits).

  • isdecimal(): Series<boolean | null>

    True where every character is a decimal digit (Unicode category Nd).

  • isnumeric(): Series<boolean | null>

    True where every character is numeric (Unicode category N, such as digits, fractions and Roman numerals).

  • isalnum(): Series<boolean | null>

    True where every character is a letter or a number.

  • isspace(): Series<boolean | null>

    True where every character is whitespace.

  • isupper(): Series<boolean | null>

    True where there is at least one cased letter and all cased letters are upper case.

  • islower(): Series<boolean | null>

    True where there is at least one cased letter and all cased letters are lower case.

Functions

3

dateRange

function dateRange(start: string | Date | number, periods: number, freq?: DateFreq, options?: SeriesOptions): Series<Date>;

Generate a range of dates at a fixed frequency.

D steps by calendar days (the time of day is kept across DST changes); H, min and S step by elapsed time. MS and YS follow pandas: the first value is the first month (or year) start on or after start, keeping the time of day, and later values step one month (or year) at a time.

Parameters

start
string | Date | number
Start date (string, Date, or epoch ms)
periods
number
Number of periods to generate
freqoptional
DateFreq
Frequency: 'D' (day), 'H' (hour), 'min' (minute), 'S' (second), 'MS' (month start), 'YS' (year start)
optionsoptional
SeriesOptions
Series options (name, index) for the result

Returns

Series<Date>Series of Dates

Throws

  • InvalidParameterErrorIf periods is not a non-negative integer, start is missing, or freq is unknown
Example
import { dateRange } from 'deepbox/dataframe';const dates = dateRange('2024-01-01', 5, 'D');// Series([Date(Jan 1), Date(Jan 2), ..., Date(Jan 5)])

timedelta

function timedelta(left: Series<unknown>, right: Series<unknown>, unit?: "ms" | "S" | "min" | "H" | "D"): Series<number | null>;

Compute the difference between two Date Series in the given unit.

Parameters

left
Series<unknown>
Left operand Series of Dates
right
Series<unknown>
Right operand Series of Dates
unitoptional
"ms" | "S" | "min" | "H" | "D"
Unit for result: 'ms', 'S', 'min', 'H', 'D'

Returns

Series<number | null>Series<number | null> of differences (left - right) in the given unit, indexed like left. A null on either side gives null.

Throws

  • DataValidationErrorIf the Series lengths differ
  • InvalidParameterErrorIf unit is unknown

toDatetime

function toDatetime(data: ReadonlyArray<string | number | Date | null | undefined>, options?: SeriesOptions): Series<Date | null>;

Parse an array of values to Date Series.

Details

Accepts strings (ISO 8601), epoch milliseconds (numbers), or Date objects. null, undefined, NaN and empty strings become null. Date-only and zone-less datetime strings are read as local time; strings with Z or an offset keep their exact instant. Out-of-range components such as 2024-02-30 throw. The returned Dates are new objects, never the input instances.

Parameters

data
ReadonlyArray<string | number | Date | null | undefined>
Array of date-like values
optionsoptional
SeriesOptions
Series options (name, index)

Returns

Series<Date | null>Series of Date objects

Throws

  • DataValidationErrorIf an element cannot be parsed as a date
Example
import { toDatetime } from 'deepbox/dataframe';const dates = toDatetime(['2024-01-01', '2024-06-15', '2024-12-31']);dates.dt.month();  // Series([1, 6, 12])

Deprecated names

2

These older spellings still work in 1.x. New code should use the names above.

  • date_rangePrefer dateRange.
  • to_datetimePrefer toDatetime.
dataframe-series.ts
import { Categorical, DataFrame, Series, dateRange, toDatetime } from "deepbox/dataframe"; const words = new Series(["Deepbox", "v1.5.0", "Docs"]);const dates = toDatetime(["2026-01-01", "2026-02-01"]);const range = dateRange("2026-01-01", 3, "D"); const df = new DataFrame({  city: ["riyadh", "jeddah"],  openedAt: dates.toArray(),}); console.log(words.str.upper().toString());console.log(words.str.contains("box").toString());console.log(dates.dt.month().toString(), dates.dt.dayName().toString());console.log(range.toString());console.log(df.toString());console.log(Categorical.from(["low", "high", "low"]).toString());