diff --git a/playground/add_sub_mul_div.html b/playground/add_sub_mul_div.html index 07fb093c..9f43f48c 100644 --- a/playground/add_sub_mul_div.html +++ b/playground/add_sub_mul_div.html @@ -192,7 +192,7 @@

2 — add: Series + Series (positional)

const a = new Series({ data: [1, 2, 3] }); const b = new Series({ data: [4, 5, 6] }); -seriesAdd(a, b).values; // [5, 7, 9] +console.log(seriesAdd(a, b).values); // [5, 7, 9]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -213,8 +213,8 @@

3 — sub / rsub

+console.log(seriesSub(s, 5).values); // [5, 15, 25] +console.log(seriesRsub(s, 100).values); // [90, 80, 70]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -235,10 +235,10 @@

4 — mul: multiply

+console.log(seriesMul(s, weights).values); // [0.5, 2, 6, null]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -261,8 +261,8 @@

5 — div / rdiv (true division)

+console.log(seriesDiv(s, 2).values); // [2, 4.5, Infinity, null] +console.log(seriesRdiv(s, 36).values); // [9, 4, Infinity, null]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -285,13 +285,13 @@

6 — DataFrame arithmetic

const df = DataFrame.fromColumns({ price: [10, 20, 30], qty: [3, 5, 2] }); // Add a discount -dataFrameAdd(df, 5).col("price").values; // [15, 25, 35] +console.log(dataFrameAdd(df, 5).col("price").values); // [15, 25, 35] // Scale everything by 2 -dataFrameMul(df, 2).col("qty").values; // [6, 10, 4] +console.log(dataFrameMul(df, 2).col("qty").values); // [6, 10, 4] // Revenue per item / some constant -dataFrameDiv(df, 10).col("price").values; // [1, 2, 3] +console.log(dataFrameDiv(df, 10).col("price").values); // [1, 2, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -312,9 +312,9 @@

7 — Missing value propagation

+console.log(seriesAdd(s, 10).values); // [11, null, NaN, 14] +console.log(seriesMul(s, 2).values); // [2, null, NaN, 8] +console.log(seriesDiv(s, 2).values); // [0.5, null, NaN, 2]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/align.html b/playground/align.html index aa8da364..2699b1e7 100644 --- a/playground/align.html +++ b/playground/align.html @@ -168,8 +168,8 @@

1 · alignSeries — outer (default)

// Default join="outer" → union of indices const [la, ra] = alignSeries(a, b); -la.toArray(); // → [1, 2, 3] (index: a, b, c) -ra.toArray(); // → [null, 10, 20] (index: a, b, c) +console.log(la.toArray()); // → [1, 2, 3] (index: a, b, c) +console.log(ra.toArray()); // → [null, 10, 20] (index: a, b, c)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -186,8 +186,8 @@

2 · alignSeries — inner join

+console.log(li.toArray()); // → [2, 3] (only shared labels: b, c) +console.log(ri.toArray()); // → [10, 20]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -208,13 +208,13 @@

3 · alignSeries — left / right join + fillValue

// join="left": result index = x's index const [ll, rl] = alignSeries(x, y, { join: "left", fillValue: 0 }); -ll.toArray(); // → [1, 2, 3] -rl.toArray(); // → [0, 10, 0] ("d" is outside x's index → dropped) +console.log(ll.toArray()); // → [1, 2, 3] +console.log(rl.toArray()); // → [0, 10, 0] ("d" is outside x's index → dropped) // join="right": result index = y's index const [lr, rr] = alignSeries(x, y, { join: "right", fillValue: 0 }); -lr.toArray(); // → [2, 0] ("b" matches, "d" is new) -rr.toArray(); // → [10, 30] +console.log(lr.toArray()); // → [2, 0] ("b" matches, "d" is new) +console.log(rr.toArray()); // → [10, 30]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -247,13 +247,13 @@

4 · alignDataFrame — outer, both axes

// la → shape [2, 3] columns: x, y, z // row r0: x=1, y=3, z=null // row r1: x=2, y=4, z=null -la.col("z").toArray(); // → [null, null] +console.log(la.col("z").toArray()); // → [null, null] // ra → shape [2, 3] columns: x, y, z // row r0: x=null, y=null, z=null // row r1: x=null, y=10, z=20 -ra.col("x").toArray(); // → [null, null] -ra.col("y").toArray(); // → [null, 10] +console.log(ra.col("x").toArray()); // → [null, null] +console.log(ra.col("y").toArray()); // → [null, 10]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -271,10 +271,10 @@

5 · alignDataFrame — axis=0 (rows only)

+console.log(la5.columns.toArray()); // → ["x", "y"] (unchanged) +console.log(ra5.columns.toArray()); // → ["y", "z"] (unchanged) +console.log(la5.index.toArray()); // → ["r0", "r1"] (outer union) +console.log(ra5.index.toArray()); // → ["r0", "r1"] (outer union)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -292,10 +292,10 @@

6 · alignDataFrame — axis=1 (columns only)

+console.log(la6.index.toArray()); // → ["r0", "r1"] (unchanged) +console.log(ra6.index.toArray()); // → ["r1"] (unchanged) +console.log(la6.columns.toArray().sort()); // → ["x", "y", "z"] +console.log(ra6.columns.toArray().sort()); // → ["x", "y", "z"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -318,8 +318,8 @@

7 · Arithmetic after alignment

const [ap, aq] = alignSeries(p, q, { fillValue: 0 }); // Now same shape — do element-wise addition const sum = ap.add(aq); -sum.toArray(); // → [100, 201, 302] -sum.index.toArray(); // → ["a", "b", "c"] +console.log(sum.toArray()); // → [100, 201, 302] +console.log(sum.index.toArray()); // → ["a", "b", "c"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/api_types.html b/playground/api_types.html index c91b3478..8a12cbd7 100644 --- a/playground/api_types.html +++ b/playground/api_types.html @@ -167,12 +167,12 @@

isScalar(val)

+console.log(isScalar(42)); // true +console.log(isScalar("hello")); // true +console.log(isScalar(null)); // true +console.log(isScalar(new Date())); // true +console.log(isScalar([1, 2])); // false +console.log(isScalar({ a: 1 })); // false
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -189,10 +189,10 @@

isListLike(val)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -209,9 +209,9 @@

isArrayLike(val)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -228,9 +228,9 @@

isDictLike(val)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -246,14 +246,14 @@

isNumber / isBool / isStringValue / isFloat / isInteger

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -270,10 +270,10 @@

isMissing(val)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -290,9 +290,9 @@

isHashable(val)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -312,20 +312,20 @@

Dtype-Level Predicates

+console.log(isFloatDtype("float32")); // true +console.log(isIntegerDtype("int64")); // true +console.log(isUnsignedIntegerDtype("uint8")); // true +console.log(isSignedIntegerDtype("int8")); // true +console.log(isStringDtype("string")); // true +console.log(isDatetimeDtype("datetime")); // true +console.log(isCategoricalDtype("category")); // true +console.log(isObjectDtype("object")); // true +console.log(isExtensionArrayDtype("category")); // true +console.log(isExtensionArrayDtype("int32")); // false
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/assign.html b/playground/assign.html index 9cdf746e..99327e6b 100644 --- a/playground/assign.html +++ b/playground/assign.html @@ -172,7 +172,8 @@

Example 1 — Array and Series

// df2.columns.values → ["a", "b", "c", "d"] // df2.col("c").values → [7, 8, 9] -// df2.col("d").values → [4, 5, 6] +// df2.col("d").values → [4, 5, 6] +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -198,7 +199,8 @@

Example 2 — Callable (chained derivations)

}); // df3.col("total").values → [11, 22, 33] -// df3.col("tax").values → [1.1, 2.2, 3.3] +// df3.col("tax").values → [1.1, 2.2, 3.3] +console.log(df3);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -218,7 +220,8 @@

Example 3 — Instance method

const df4 = df.assign({ squared_a: (d: DataFrame) => d.col("a").values.map((v) => (v as number) ** 2), }); -// df4.col("squared_a").values → [1, 4, 9] +// df4.col("squared_a").values → [1, 4, 9] +console.log(df4);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -238,7 +241,8 @@

Example 4 — Replace an existing column

const df5 = dataFrameAssign(df, { b: [100, 200, 300] }); // df5.columns.values → ["a", "b"] (order unchanged) -// df5.col("b").values → [100, 200, 300] +// df5.col("b").values → [100, 200, 300] +console.log(df5);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/at_iat.html b/playground/at_iat.html index 5d4d782b..d7029e21 100644 --- a/playground/at_iat.html +++ b/playground/at_iat.html @@ -186,8 +186,8 @@

seriesAt — access by label

+console.log(seriesAt(s, "b")); // 20 +console.log(seriesAt(s, "a")); // 10
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -224,8 +224,8 @@

seriesIat — access by integer position

+console.log(seriesIat(s, 2)); // 30 +console.log(seriesIat(s, -1)); // 30
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -266,8 +266,8 @@

dataFrameAt — access by row label and column name

{ x: [1, 2], y: [3, 4] }, { index: ["r0", "r1"] }, ); -dataFrameAt(df, "r1", "x"); // 2 -dataFrameAt(df, "r0", "y"); // 3 +console.log(dataFrameAt(df, "r1", "x")); // 2 +console.log(dataFrameAt(df, "r0", "y")); // 3
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -304,8 +304,8 @@

dataFrameIat — access by integer row and column position

+console.log(dataFrameIat(df, 0, 1)); // 3 (row 0, column index 1 = "y") +console.log(dataFrameIat(df, 1, -1)); // 4 (last column, row 1)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/attrs.html b/playground/attrs.html index 9e747813..52aab333 100644 --- a/playground/attrs.html +++ b/playground/attrs.html @@ -180,14 +180,14 @@

Basic usage

notes: "Morning readings", }); -getAttrs(df); +console.log(getAttrs(df)); // → { source: "weather_station_42", unit: "Celsius", notes: "Morning readings" } -getAttr(df, "unit"); // → "Celsius" -getAttr(df, "missing"); // → undefined -attrsCount(df); // → 3 -attrsKeys(df); // → ["source", "unit", "notes"] -hasAttrs(df); // → true +console.log(getAttr(df, "unit")); // → "Celsius" +console.log(getAttr(df, "missing")); // → undefined +console.log(attrsCount(df)); // → 3 +console.log(attrsKeys(df)); // → ["source", "unit", "notes"] +console.log(hasAttrs(df)); // → true
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -204,14 +204,14 @@

Merging and updating

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -230,17 +230,17 @@

Propagating metadata to derived objects

+console.log(setAttr(derived, "unit", "Fahrenheit")); +console.log(getAttrs(derived)); // → { unit: "Fahrenheit", source: "sensor_A" } +console.log(getAttrs(s)); // → { unit: "Celsius", source: "sensor_A" } ← unchanged
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -264,7 +264,7 @@

Fluent helper — withAttrs

); annotated === annotated; // true — same reference, not a copy -getAttrs(annotated); +console.log(getAttrs(annotated)); // → { source: "lab_experiment", date: "2026-04-09" }
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -284,13 +284,13 @@

Merging from multiple sources

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -307,13 +307,13 @@

Clearing metadata

- +console.log(clearAttrs(df)); +console.log(hasAttrs(df)); // → false +console.log(getAttrs(df)); // → {}
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/between.html b/playground/between.html index 42d725c0..eec2cda7 100644 --- a/playground/between.html +++ b/playground/between.html @@ -192,7 +192,7 @@

seriesBetween — inclusive="both" (default)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -242,13 +242,13 @@

Inclusive options

const s = new Series({ data: [1, 2, 3, 4, 5] }); -seriesBetween(s, 2, 4, { inclusive: "left" }).values; +console.log(seriesBetween(s, 2, 4, { inclusive: "left" }).values); // [false, true, true, false, false] -seriesBetween(s, 2, 4, { inclusive: "right" }).values; +console.log(seriesBetween(s, 2, 4, { inclusive: "right" }).values); // [false, false, true, true, false] -seriesBetween(s, 2, 4, { inclusive: "neither" }).values; +console.log(seriesBetween(s, 2, 4, { inclusive: "neither" }).values); // [false, false, true, false, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -291,7 +291,7 @@

Missing values

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -333,7 +333,7 @@

String comparison

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/clip_advanced.html b/playground/clip_advanced.html index a4f5ac8d..8798874a 100644 --- a/playground/clip_advanced.html +++ b/playground/clip_advanced.html @@ -194,7 +194,7 @@

Demo 1 — clipAdvancedSeries with scalar bounds

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -214,7 +214,7 @@

Demo 2 — clipAdvancedSeries with per-element array bounds

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -234,7 +234,7 @@

Demo 3 — clipAdvancedSeries with Series bounds

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -255,8 +255,8 @@

Demo 4 — clipAdvancedDataFrame with DataFrame bounds

const lo = DataFrame.fromColumns({ a: [2, 3, 4], b: [1, 4, 8] }); const hi = DataFrame.fromColumns({ a: [3, 7, 8], b: [5, 9, 12] }); const result = clipAdvancedDataFrame(df, { lower: lo, upper: hi }); -result.col("a").values; // → [2, 5, 8] -result.col("b").values; // → [2, 6, 10] +console.log(result.col("a").values); // → [2, 5, 8] +console.log(result.col("b").values); // → [2, 6, 10]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -276,8 +276,8 @@

Demo 5 — clipAdvancedDataFrame with Series broadcast (axis=1)

const df = DataFrame.fromColumns({ a: [1, 5, 9], b: [2, 6, 10] }); const loPerRow = new Series({ data: [0, 4, 10] }); const result = clipAdvancedDataFrame(df, { lower: loPerRow, axis: 1 }); -result.col("a").values; // → [1, 5, 10] -result.col("b").values; // → [2, 6, 10] +console.log(result.col("a").values); // → [1, 5, 10] +console.log(result.col("b").values); // → [2, 6, 10]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/clip_with_bounds.html b/playground/clip_with_bounds.html index 27bfd394..f3df881e 100644 --- a/playground/clip_with_bounds.html +++ b/playground/clip_with_bounds.html @@ -165,7 +165,7 @@

Example 1 — Series with scalar bounds

const s = new Series({ data: [-5, 1, 7, 12] }); -clipSeriesWithBounds(s, { lower: 0, upper: 8 }).values; +console.log(clipSeriesWithBounds(s, { lower: 0, upper: 8 }).values); // [0, 1, 7, 8]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -196,7 +196,7 @@

Example 2 — Series bounds (label-aligned)

index: new Index(["AAPL", "MSFT", "GOOG"]), }); -clipSeriesWithBounds(prices, { lower: floors }).values; +console.log(clipSeriesWithBounds(prices, { lower: floors }).values); // AAPL: max(90, 95)=95 GOOG: max(110, 100)=110 MSFT: max(85, 80)=85 AMZN: 120 (no bound) // [95, 110, 85, 120]
Click ▶ Run to execute
@@ -227,7 +227,8 @@

Example 3 — DataFrame clip with per-column bounds (axis=1)

const result = clipDataFrameWithBounds(df, { lower: lo, upper: hi, axis: 1 }); // col "a": [1, 5, 10] (lower=1, upper=10) -// col "b": [4, 8, 9] (lower=4, upper=9) +// col "b": [4, 8, 9] (lower=4, upper=9) +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -255,7 +256,8 @@

Example 4 — DataFrame clip with per-row bounds (axis=0, default)

const upperBound = new Series({ data: [12, 12, 20, 20] }); // row-specific caps const result = clipDataFrameWithBounds(df, { lower: lowerBound, upper: upperBound, axis: 0 }); -// min_temp: [0, 0, 1, 4] max_temp: [10, 12, 18, 20] +// min_temp: [0, 0, 1, 4] max_temp: [10, 12, 18, 20] +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -278,7 +280,8 @@

Example 5 — Element-wise DataFrame bounds

const hi = DataFrame.fromColumns({ a: [8, 8, 8], b: [5, 5, 5] }); const result = clipDataFrameWithBounds(df, { lower: lo, upper: hi }); -// col "a": [3, 5, 8] col "b": [2, 5, 3] +// col "a": [3, 5, 8] col "b": [2, 5, 3] +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -297,7 +300,7 @@

Null / NaN propagation

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/combine.html b/playground/combine.html index 617a8e08..b3114782 100644 --- a/playground/combine.html +++ b/playground/combine.html @@ -172,12 +172,12 @@

Code Examples

const b = new Series({ data: [10, 2, 30], index: [0, 1, 2] }); // Element-wise max -combineSeries(a, b, (x, y) => Math.max(x, y)).values; // [10, 5, 30] +console.log(combineSeries(a, b, (x, y) => Math.max(x, y)).values); // [10, 5, 30] // Union index with fillValue=0 const c = new Series({ data: [1, 2], index: ["x", "y"] }); const d = new Series({ data: [10, 30], index: ["x", "z"] }); -combineSeries(c, d, (x, y) => (x ?? 0) + (y ?? 0), 0).values; +console.log(combineSeries(c, d, (x, y) => (x ?? 0) + (y ?? 0), 0).values); // x:11, y:2, z:30 // ── DataFrame ─────────────────────────────────────────────────────────────── @@ -185,7 +185,7 @@

Code Examples

const df2 = DataFrame.fromColumns({ a: [10, 2], c: [1000, 2000] }); // Shared column "a": element-wise min; unshared columns processed with fillValue -combineDataFrame(df1, df2, (p, q) => Math.min(p ?? Infinity, q ?? Infinity)); +console.log(combineDataFrame(df1, df2, (p, q) => Math.min(p ?? Infinity, q ?? Infinity))); // overwrite: false — unshared columns preserved as-is combineDataFrame(df1, df2, (p, q) => Math.min(p ?? Infinity, q ?? Infinity), diff --git a/playground/combine_first.html b/playground/combine_first.html index 0c664c8d..5ba8f393 100644 --- a/playground/combine_first.html +++ b/playground/combine_first.html @@ -173,7 +173,8 @@

Example 1 — Series: fill gaps with values from another Series

// - "x": a has 1 (non-null) → keeps 1 // - "y": a has null → filled from b → 20 // - "z": a has 3 (non-null) → keeps 3 -// - "w": a has no entry → comes from b → 40 +// - "w": a has no entry → comes from b → 40 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -212,7 +213,8 @@

Example 2 — DataFrame: patch missing cells across row/column union

// result["r2"]["y"] = null (no r2 in a, no y in b) // result["r0"]["z"] = 30 (b only) // result["r1"]["z"] = null (b has no r1) -// result["r2"]["z"] = 40 (b only) +// result["r2"]["z"] = 40 (b only) +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -243,7 +245,8 @@

Example 3 — NaN is treated as missing

const merged = combineFirstSeries(sensor1, sensor2); // values: [21.0, 22.5, 23.1, 24.0] -// Gaps in sensor1 filled from sensor2 +// Gaps in sensor1 filled from sensor2 +console.log(merged);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -275,7 +278,8 @@

Example 4 — Temporal data backfill

const complete = combineFirstSeries(primary, backup); // index: 2024-01, 2024-02, 2024-03, 2024-04, 2024-05, 2024-06 -// values: 100, 101, 102, 103, 104, 106 +// values: 100, 101, 102, 103, 104, 106 +console.log(complete);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/compare.html b/playground/compare.html index 7978f62d..dfd3fc32 100644 --- a/playground/compare.html +++ b/playground/compare.html @@ -170,7 +170,8 @@

1 — seriesEq with a scalar

// → [false, true, false, true, false] // Use this as a boolean mask for filtering: -// s.values.filter((_, i) => result.values[i]) → [2, 2] +// s.values.filter((_, i) => result.values[i]) → [2, 2] +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -191,7 +192,7 @@

2 — seriesNe: inequality

const s = new Series({ data: ["apple", "banana", "apple", "cherry"] }); -seriesNe(s, "apple").values; +console.log(seriesNe(s, "apple").values); // → [false, true, false, true]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -213,8 +214,8 @@

3 — Ordering comparisons: lt, gt, le, ge

const scores = new Series({ data: [45, 72, 88, 60, 95] }); -seriesLt(scores, 60).values; // [true, false, false, false, false] -seriesGe(scores, 60).values; // [false, true, true, true, true] +console.log(seriesLt(scores, 60).values); // [true, false, false, false, false] +console.log(seriesGe(scores, 60).values); // [false, true, true, true, true] // lt and ge are always complementary for finite, non-null values: // lt[i] !== ge[i] for every i @@ -239,8 +240,8 @@

4 — Comparing two Series element-by-element

const actual = new Series({ data: [1, 2, 3, 4] }); const expected = new Series({ data: [1, 3, 3, 2] }); -seriesEq(actual, expected).values; // [true, false, true, false] -seriesLt(actual, expected).values; // [false, true, false, false] +console.log(seriesEq(actual, expected).values); // [true, false, true, false] +console.log(seriesLt(actual, expected).values); // [false, true, false, false] // Throws RangeError if lengths differ
Click ▶ Run to execute
@@ -264,12 +265,12 @@

5 — Missing value behaviour

const s = new Series({ data: [1, null, NaN, 3] }); -seriesEq(s, 1).values; // [true, false, false, false] -seriesNe(s, 1).values; // [false, false, false, true ] -seriesLt(s, 2).values; // [true, false, false, false] +console.log(seriesEq(s, 1).values); // [true, false, false, false] +console.log(seriesNe(s, 1).values); // [false, false, false, true ] +console.log(seriesLt(s, 2).values); // [true, false, false, false] // null eq null → false (NaN != NaN convention) -seriesEq(s, null).values; // [false, false, false, false] +console.log(seriesEq(s, null).values); // [false, false, false, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -293,10 +294,10 @@

6 — DataFrame comparison with a scalar

science: [60, 45, 91], }); -dataFrameGt(df, 60).col("math").values; +console.log(dataFrameGt(df, 60).col("math").values); // → [false, true, true] -dataFrameLe(df, 60).col("science").values; +console.log(dataFrameLe(df, 60).col("science").values); // → [true, true, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -319,8 +320,8 @@

7 — DataFrame compared against another DataFrame

const df1 = DataFrame.fromColumns({ a: [1, 2], b: [3, 4] }); const df2 = DataFrame.fromColumns({ a: [1, 0], b: [3, 5] }); -dataFrameEq(df1, df2).col("a").values; // [true, false] -dataFrameEq(df1, df2).col("b").values; // [true, false] +console.log(dataFrameEq(df1, df2).col("a").values); // [true, false] +console.log(dataFrameEq(df1, df2).col("b").values); // [true, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -345,7 +346,7 @@

8 — Combining with whereSeries for conditional selection

const isWarm = seriesGe(temps, 20); // [false, true, true, false, true] const warmOnly = whereSeries(temps, isWarm); -warmOnly.values; // [null, 22, 30, null, 27] +console.log(warmOnly.values); // [null, 22, 30, null, 27]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/corrwith.html b/playground/corrwith.html index eb19c248..507460d4 100644 --- a/playground/corrwith.html +++ b/playground/corrwith.html @@ -197,15 +197,15 @@

autoCorr — lag-N autocorrelation

+console.log(autoCorr(flat, 1)); // NaN
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -258,7 +258,8 @@

corrWith — DataFrame correlated with a Series

const s = new Series({ data: [1, 2, 3, 4, 5] }); const result = corrWith(df, s); -// Series(A=1.0, B=-1.0) indexed by column names +// Series(A=1.0, B=-1.0) indexed by column names +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -316,11 +317,11 @@

corrWith — DataFrame correlated with another DataFrame

const df1 = DataFrame.fromColumns({ A: [1, 2, 3], B: [4, 5, 6] }); const df2 = DataFrame.fromColumns({ A: [1, 2, 3], B: [6, 5, 4] }); -corrWith(df1, df2); // A=1.0, B=-1.0 +console.log(corrWith(df1, df2)); // A=1.0, B=-1.0 const df3 = DataFrame.fromColumns({ A: [1, 2, 3], C: [7, 8, 9] }); -corrWith(df1, df3); // A=1.0, B=NaN, C=NaN -corrWith(df1, df3, { drop: true }); // A=1.0 +console.log(corrWith(df1, df3)); // A=1.0, B=NaN, C=NaN +console.log(corrWith(df1, df3, { drop: true })); // A=1.0
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -371,7 +372,7 @@

corrWith — axis=1 (row-wise correlation)

const df = DataFrame.fromColumns({ A: [1, 2], B: [2, 4], C: [3, 6] }); const s = new Series({ data: [1, 2, 3] }); -corrWith(df, s, { axis: 1 }); +console.log(corrWith(df, s, { axis: 1 })); // Series([1.0, 1.0]) indexed by row labels [0, 1]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/cut_bins_to_frame.html b/playground/cut_bins_to_frame.html index 4a89d55e..2f7e3a46 100644 --- a/playground/cut_bins_to_frame.html +++ b/playground/cut_bins_to_frame.html @@ -177,7 +177,8 @@

What it does

// { "(0.0, 25.0]": 5, "(25.0, 50.0]": 6, ... } // Just edges indexed by label -const edges = binEdges(result); +const edges = binEdges(result); +console.log(edges);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/cut_qcut.html b/playground/cut_qcut.html index a3ac8533..b500e7e3 100644 --- a/playground/cut_qcut.html +++ b/playground/cut_qcut.html @@ -173,7 +173,8 @@

Integer bins

// labels: ["(5.0, 26.7]", "(26.7, 48.3]", "(48.3, 70.0]"] // bins: [4.935, 26.667, 48.333, 70] // codes: [0, 0, 0, 1, 1, 2] -console.table(ages.map((a, i) => ({ age: a, bin: labels[codes[i]!] }))); +console.table(ages.map((a, i) => ({ age: a, bin: labels[codes[i]!] }))); +console.log(ages);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -196,7 +197,8 @@

Explicit bin edges

}); // codes: [0, 1, 2, 3, 4, 4] // labels[codes[0]] → "F" -// labels[codes[5]] → "A" +// labels[codes[5]] → "A" +console.log(scores);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -218,7 +220,8 @@

Quartile split

const { codes, labels, bins } = qcut(values, 4); // labels: ["[1, 3.25]", "(3.25, 5.5]", "(5.5, 7.75]", "(7.75, 10]"] -// Every bin has ~2-3 elements +// Every bin has ~2-3 elements +console.log(values);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/date-offset.html b/playground/date-offset.html index a779f47e..5136589b 100644 --- a/playground/date-offset.html +++ b/playground/date-offset.html @@ -173,7 +173,8 @@

2 — Fixed-time offsets (Day, Hour, Minute, Second, Milli)

new Hour(2).apply(d).toISOString(); // "2024-01-01T02:00:00.000Z" new Minute(90).apply(d).toISOString(); // "2024-01-01T01:30:00.000Z" new Second(30).apply(d).toISOString(); // "2024-01-01T00:00:30.000Z" -new Milli(500).apply(d).getTime() - d.getTime(); // 500 +new Milli(500).apply(d).getTime() - d.getTime(); // 500 +console.log(d);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -202,16 +203,16 @@

3 — Week offset

// Weekday-aligned (weekday=0 → Monday) const wk = new Week(1, { weekday: 0 }); -wk.apply(wed).toISOString().slice(0, 10); // "2024-01-22" (next Mon) -wk.apply(mon).toISOString().slice(0, 10); // "2024-01-22" (Mon → next Mon) +console.log(wk.apply(wed).toISOString().slice(0, 10)); // "2024-01-22" (next Mon) +console.log(wk.apply(mon).toISOString().slice(0, 10)); // "2024-01-22" (Mon → next Mon) // Rollforward / rollback -wk.rollforward(wed).toISOString().slice(0, 10); // "2024-01-22" -wk.rollback(wed).toISOString().slice(0, 10); // "2024-01-15" +console.log(wk.rollforward(wed).toISOString().slice(0, 10)); // "2024-01-22" +console.log(wk.rollback(wed).toISOString().slice(0, 10)); // "2024-01-15" // onOffset -wk.onOffset(mon); // true -wk.onOffset(wed); // false +console.log(wk.onOffset(mon)); // true +console.log(wk.onOffset(wed)); // false
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -248,7 +249,8 @@

4 — MonthEnd & MonthBegin

new MonthBegin(-1).apply(mid).toISOString().slice(0, 10); // "2024-01-01" new MonthBegin(0).rollforward(mid).toISOString().slice(0, 10); // "2024-02-01" -new MonthBegin(0).rollback(mid).toISOString().slice(0, 10); // "2024-01-01" +new MonthBegin(0).rollback(mid).toISOString().slice(0, 10); // "2024-01-01" +console.log(end);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -279,7 +281,8 @@

5 — YearEnd & YearBegin

const yr2024 = new Date(Date.UTC(2024, 11, 31)); new YearEnd(0).rollforward(yr2024).toISOString().slice(0, 10); // "2024-12-31" -new YearEnd(0).rollback(d).toISOString().slice(0, 10); // "2023-12-31" +new YearEnd(0).rollback(d).toISOString().slice(0, 10); // "2023-12-31" +console.log(yr2024);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -316,7 +319,8 @@

6 — BusinessDay

new BusinessDay(0).rollback(sat).toISOString().slice(0, 10); // "2024-01-12" new BusinessDay(0).onOffset(fri); // true -new BusinessDay(0).onOffset(sat); // false +new BusinessDay(0).onOffset(sat); // false +console.log(sat);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -344,7 +348,7 @@

7 — multiply & negate

const bday = new BusinessDay(3); const fri = new Date(Date.UTC(2024, 0, 12)); -bday.negate().apply(bday.apply(fri)).toISOString().slice(0, 10); // "2024-01-12" +console.log(bday.negate().apply(bday.apply(fri)).toISOString().slice(0, 10)); // "2024-01-12"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -365,10 +369,10 @@

8 — Static factory methods

const d = new Date(Date.UTC(2024, 0, 15)); -Day.of(5).apply(d).toISOString().slice(0, 10); // "2024-01-20" -MonthEnd.of(1).apply(d).toISOString().slice(0, 10); // "2024-01-31" -Week.of(1, { weekday: 0 }).apply(d).toISOString().slice(0, 10); // "2024-01-22" -BusinessDay.of(2).apply(d).toISOString().slice(0, 10); // "2024-01-17" +console.log(Day.of(5).apply(d).toISOString().slice(0, 10)); // "2024-01-20" +console.log(MonthEnd.of(1).apply(d).toISOString().slice(0, 10)); // "2024-01-31" +console.log(Week.of(1, { weekday: 0 }).apply(d).toISOString().slice(0, 10)); // "2024-01-22" +console.log(BusinessDay.of(2).apply(d).toISOString().slice(0, 10)); // "2024-01-17"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/dot_matmul.html b/playground/dot_matmul.html index 9f53494f..fa74a324 100644 --- a/playground/dot_matmul.html +++ b/playground/dot_matmul.html @@ -167,16 +167,16 @@

API

import { seriesDotSeries, seriesDotDataFrame, dataFrameDotSeries, dataFrameDotDataFrame } from "tsb"; // Series · Series → scalar -seriesDotSeries(a, b); +console.log(seriesDotSeries(a, b)); // Series · DataFrame → Series -seriesDotDataFrame(s, df); +console.log(seriesDotDataFrame(s, df)); // DataFrame · Series → Series -dataFrameDotSeries(df, s); +console.log(dataFrameDotSeries(df, s)); // DataFrame · DataFrame → DataFrame -dataFrameDotDataFrame(A, B); +console.log(dataFrameDotDataFrame(A, B));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -196,17 +196,17 @@

Examples

// Series dot product const a = new Series({ data: [1, 2, 3], index: ["x","y","z"] }); const b = new Series({ data: [4, 5, 6], index: ["x","y","z"] }); -seriesDotSeries(a, b); // 1*4 + 2*5 + 3*6 = 32 +console.log(seriesDotSeries(a, b)); // 1*4 + 2*5 + 3*6 = 32 // DataFrame · vector const df = DataFrame.fromColumns({ a: [1, 2], b: [3, 4] }); const v = new Series({ data: [1, 1], index: ["a", "b"] }); -dataFrameDotSeries(df, v).values; // [4, 6] (row sums) +console.log(dataFrameDotSeries(df, v).values); // [4, 6] (row sums) // Matrix multiply const A = DataFrame.fromColumns({ k: [1, 2] }); // 2×1 // ... B with row index ["k"] ... -dataFrameDotDataFrame(A, B).col("r").values; // [3, 6] +console.log(dataFrameDotDataFrame(A, B).col("r").values); // [3, 6]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/dropna.html b/playground/dropna.html index 73aa6480..b8d57d92 100644 --- a/playground/dropna.html +++ b/playground/dropna.html @@ -166,8 +166,8 @@

Example 1 — Series: drop missing elements

const s = new Series({ data: [1, null, NaN, 4, undefined, 6] }); const clean = dropna(s); -clean.values; // [1, 4, 6] -clean.size; // 3 +console.log(clean.values); // [1, 4, 6] +console.log(clean.size); // 3
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -193,7 +193,7 @@

Example 2 — DataFrame: drop rows with any missing value (default)

// Drop any row that has at least one null const clean = dropna(df); -clean.shape; // [1, 3] — only "Alice" row survives (score=95, grade="A") +console.log(clean.shape); // [1, 3] — only "Alice" row survives (score=95, grade="A")
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -219,7 +219,7 @@

Example 3 — how = "all": only drop fully-null rows

// Row 1: both null → dropped // Row 0 and Row 2: at least one non-null → kept const clean = dropna(df, { how: "all" }); -clean.shape; // [2, 2] +console.log(clean.shape); // [2, 2]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -248,7 +248,7 @@

Example 4 — thresh: require at least N non-null values

// Row 1: 0 present → drop // Row 2: 2 present → keep const clean = dropna(df, { thresh: 2 }); -clean.shape; // [2, 3] +console.log(clean.shape); // [2, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -275,7 +275,7 @@

Example 5 — subset: only check specific columns

// Only check the "score" column for nulls — ignore "notes" const clean = dropna(df, { subset: ["score"] }); // Row 1 (score=null) is dropped; Row 2 (notes=null but score=88) is kept. -clean.shape; // [2, 3] +console.log(clean.shape); // [2, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -300,8 +300,8 @@

Example 6 — axis = 1: drop columns with missing values

}); const clean = dropna(df, { axis: 1 }); -clean.columns.toArray(); // ["b"] -clean.shape; // [3, 1] +console.log(clean.columns.toArray()); // ["b"] +console.log(clean.shape); // [3, 1]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -326,7 +326,7 @@

Example 7 — axis = 1, how = "all": only drop all-null columns

}); const clean = dropna(df, { axis: 1, how: "all" }); -clean.columns.toArray(); // ["b", "c"] +console.log(clean.columns.toArray()); // ["b", "c"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/duplicated.html b/playground/duplicated.html index 21b3fffd..0f03a116 100644 --- a/playground/duplicated.html +++ b/playground/duplicated.html @@ -170,7 +170,7 @@

Example 1 — Basic: find duplicate rows

// Row 2 ("Alice", 90) is a duplicate of Row 0 const mask = duplicatedDataFrame(df); -mask.values; // [false, false, true, false] +console.log(mask.values); // [false, false, true, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -194,7 +194,7 @@

Example 2 — Drop duplicate rows

}); const deduped = dropDuplicatesDataFrame(df); -deduped.shape; // [3, 2] — "Alice" row 2 removed +console.log(deduped.shape); // [3, 2] — "Alice" row 2 removed
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -219,7 +219,7 @@

Example 3 — subset: only check specific columns

// Drop based on "id" only — row 2 (id=1) is dup even though value differs const deduped = dropDuplicatesDataFrame(df, { subset: ["id"] }); -deduped.shape; // [3, 2] +console.log(deduped.shape); // [3, 2]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -242,11 +242,11 @@

Example 4 — keep="last": keep the last occurrence

}); // keep="last" → mark the FIRST occurrence of each dup, keep the last -duplicatedDataFrame(df, { keep: "last" }).values; +console.log(duplicatedDataFrame(df, { keep: "last" }).values); // [true, false, false, false] // keep=false → mark ALL occurrences of any duplicate -duplicatedDataFrame(df, { keep: false }).values; +console.log(duplicatedDataFrame(df, { keep: false }).values); // [true, false, true, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -267,11 +267,11 @@

Example 5 — Series: deduplicate values

const s = new Series({ data: [1, 2, 1, 3, 2, 4] }); -duplicatedSeries(s).values; // [false, false, true, false, true, false] -dropDuplicatesSeries(s).values; // [1, 2, 3, 4] +console.log(duplicatedSeries(s).values); // [false, false, true, false, true, false] +console.log(dropDuplicatesSeries(s).values); // [1, 2, 3, 4] // keep=false → mark all duplicate values -duplicatedSeries(s, { keep: false }).values; +console.log(duplicatedSeries(s, { keep: false }).values); // [true, true, true, false, true, false]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/eval_query.html b/playground/eval_query.html index 9e2bdedb..f0e5d47a 100644 --- a/playground/eval_query.html +++ b/playground/eval_query.html @@ -186,26 +186,26 @@

queryDataFrame(df, expr)

}); // Simple comparison -queryDataFrame(df, "age > 28"); +console.log(queryDataFrame(df, "age > 28")); // name: ["Bob", "Dave"] age: [32, 45] score: [72, 60] // Combined conditions -queryDataFrame(df, "age < 35 and score >= 85"); +console.log(queryDataFrame(df, "age < 35 and score >= 85")); // name: ["Alice", "Carol"] // String equality -queryDataFrame(df, "name == 'Alice'"); +console.log(queryDataFrame(df, "name == 'Alice'")); // single row // 'in' operator -queryDataFrame(df, "name in ['Alice', 'Carol']"); +console.log(queryDataFrame(df, "name in ['Alice', 'Carol']")); // 'not in' operator -queryDataFrame(df, "age not in [25, 45]"); +console.log(queryDataFrame(df, "age not in [25, 45]")); // Backtick-quoted column (for names with spaces) const df2 = DataFrame.fromArrays({ "first name": ["Alice", "Bob"] }); -queryDataFrame(df2, "`first name` == 'Alice'"); +console.log(queryDataFrame(df2, "`first name` == 'Alice'"));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -228,20 +228,20 @@

evalDataFrame(df, expr)

}); // Arithmetic expression → new Series -evalDataFrame(sales, "price * qty"); +console.log(evalDataFrame(sales, "price * qty")); // Series [1000, 1250, 1000, 400] // Boolean expression (useful as a mask) -evalDataFrame(sales, "price > 10"); +console.log(evalDataFrame(sales, "price > 10")); // Series [false, true, false, true] // Function calls -evalDataFrame(sales, "round(price * qty / 100, 1)"); +console.log(evalDataFrame(sales, "round(price * qty / 100, 1)")); // Series [10.0, 12.5, 10.0, 4.0] // String operations const df3 = DataFrame.fromArrays({ tag: ["Foo", "Bar", "Baz"] }); -evalDataFrame(df3, "lower(tag)"); +console.log(evalDataFrame(df3, "lower(tag)")); // Series ["foo", "bar", "baz"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/excel.html b/playground/excel.html index 17450425..20468164 100644 --- a/playground/excel.html +++ b/playground/excel.html @@ -221,9 +221,9 @@

Advanced example

const df3 = readExcel(buffer, { naValues: ["N/A", "MISSING", "-"] }); // DataFrame operations work immediately -df.describe(); -df.col("revenue").sum(); -df.groupby("region").mean(); +console.log(df.describe()); +console.log(df.col("revenue").sum()); +console.log(df.groupby("region").mean());
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/fillna.html b/playground/fillna.html index 503664b4..4f04fdeb 100644 --- a/playground/fillna.html +++ b/playground/fillna.html @@ -167,11 +167,11 @@

1 · Scalar fill

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -194,12 +194,12 @@

2 · Forward fill (ffill / pad)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -222,12 +222,12 @@

3 · Backward fill (bfill / backfill)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -250,11 +250,11 @@

4 · Limiting the fill — limit

// Only fill up to 1 consecutive missing value const s = new Series({ data: [1, null, null, null, 5] }); -fillnaSeries(s, { method: "ffill", limit: 1 }).values; +console.log(fillnaSeries(s, { method: "ffill", limit: 1 }).values); // → [1, 1, null, null, 5] // bfill with limit=2 -fillnaSeries(s, { method: "bfill", limit: 2 }).values; +console.log(fillnaSeries(s, { method: "bfill", limit: 2 }).values); // → [null, null, 5, 5, 5]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -281,8 +281,8 @@

5 · DataFrame — scalar fill

}); const result = fillnaDataFrame(df, { value: 0 }); -result.col("a").values; // [1, 0, 3] -result.col("b").values; // [0, 2, 0] +console.log(result.col("a").values); // [1, 0, 3] +console.log(result.col("b").values); // [0, 2, 0]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -309,9 +309,9 @@

6 · DataFrame — per-column fill map

}); const result = fillnaDataFrame(df, { value: { a: -1, b: 99 } }); -result.col("a").values; // [-1, 2, -1] -result.col("b").values; // [1, 99, 3] -result.col("c").values; // [null, null, null] ← untouched +console.log(result.col("a").values); // [-1, 2, -1] +console.log(result.col("b").values); // [1, 99, 3] +console.log(result.col("c").values); // [null, null, null] ← untouched
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -340,9 +340,9 @@

7 · DataFrame — method fill (axis=0 / axis=1)

// axis=0 (default): ffill down each column const byCol = fillnaDataFrame(df, { method: "ffill" }); -byCol.col("a").values; // [1, 1, 1] -byCol.col("b").values; // [null, 2, 2] -byCol.col("c").values; // [null, null, 3] +console.log(byCol.col("a").values); // [1, 1, 1] +console.log(byCol.col("b").values); // [null, 2, 2] +console.log(byCol.col("c").values); // [null, null, 3] // axis=1: bfill across each row const byRow = fillnaDataFrame(df, { method: "bfill", axis: 1 }); @@ -381,8 +381,8 @@

8 · DataFrame — fill values from a Series

}); const result = fillnaDataFrame(df, { value: fills }); -result.col("price").values; // [10, 0, 30] -result.col("volume").values; // [0, 200, 0] +console.log(result.col("price").values); // [10, 0, 30] +console.log(result.col("volume").values); // [0, 200, 0]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/filter.html b/playground/filter.html index 55522997..df7fce5d 100644 --- a/playground/filter.html +++ b/playground/filter.html @@ -187,7 +187,7 @@

filterDataFrame — by items (column names)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -229,7 +229,7 @@

filterDataFrame — by like (substring)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -271,7 +271,7 @@

filterDataFrame — by regex

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -316,7 +316,7 @@

filterDataFrame — filter rows (axis=0)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -358,7 +358,7 @@

filterSeries — by label

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/format_ops.html b/playground/format_ops.html index 9865ec42..d8ce6c3d 100644 --- a/playground/format_ops.html +++ b/playground/format_ops.html @@ -173,9 +173,9 @@

Formatter factories

const fmtPct = makePercentFormatter(1); // (v) => formatPercent(v, 1) const fmtDollar = makeCurrencyFormatter("$"); // (v) => formatCurrency(v, "$", 2) -fmtFloat(3.14159); // "3.142" -fmtPct(0.0825); // "8.3%" -fmtDollar(9999.99); // "$9,999.99" +console.log(fmtFloat(3.14159)); // "3.142" +console.log(fmtPct(0.0825)); // "8.3%" +console.log(fmtDollar(9999.99)); // "$9,999.99"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -196,7 +196,8 @@

Apply to a Series

const returns = new Series({ data: [0.05, -0.02, 0.134, 0.007], name: "returns" }); const formatted = applySeriesFormatter(returns, makePercentFormatter(1)); -// Series<string> ["5.0%", "-2.0%", "13.4%", "0.7%"] +// Series<string> ["5.0%", "-2.0%", "13.4%", "0.7%"] +console.log(formatted);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -229,7 +230,8 @@

Apply to a DataFrame

// price: ["$1,299.99", "$899.50", "$45.00"], // change: ["2.50%", "-3.10%", "10.20%"], // volume: ["15000", "8200", "230000"], // no formatter → String(v) -// } +// } +console.log(formatted);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/infer_dtype.html b/playground/infer_dtype.html index c49c0d17..b7d94f53 100644 --- a/playground/infer_dtype.html +++ b/playground/infer_dtype.html @@ -163,14 +163,14 @@

Example 1 — basic scalar types

+console.log(inferDtype([1, 2, 3])); // "integer" +console.log(inferDtype([1.1, 2.2, 3.3])); // "floating" +console.log(inferDtype([1, 2.5, 3])); // "mixed-integer-float" +console.log(inferDtype([true, false, true])); // "boolean" +console.log(inferDtype(["a", "b", "c"])); // "string" +console.log(inferDtype([])); // "empty" +console.log(inferDtype([null, null])); // "empty" (skipna=true by default) +console.log(inferDtype([null, null], { skipna: false })); // "mixed"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -189,13 +189,13 @@

Example 2 — working with Series

+console.log(inferDtype(s3)); // "integer" (nulls skipped by default)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -213,16 +213,16 @@

Example 3 — specialised tsb types

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -241,11 +241,11 @@

Example 4 — mixed types

+console.log(inferDtype([1, "a", 2])); // "mixed-integer" (int + non-numeric non-float) +console.log(inferDtype(["a", true, null])); // "mixed" (string + bool) +console.log(inferDtype([1n, 2n, 3n])); // "integer" (bigint only) +console.log(inferDtype([1n, 2])); // "decimal" (bigint + integer) +console.log(inferDtype([1n, 2.5])); // "mixed-integer-float"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/infer_objects.html b/playground/infer_objects.html index 2a0e6d1d..4b697337 100644 --- a/playground/infer_objects.html +++ b/playground/infer_objects.html @@ -166,19 +166,19 @@

inferObjectsSeries — promote object → typed

// Object series holding integers const s = new Series({ data: [1, 2, 3], dtype: Dtype.object }); -s.dtype.kind; // "object" +console.log(s.dtype.kind); // "object" const better = inferObjectsSeries(s); -better.dtype.kind; // "int" -better.values; // [1, 2, 3] +console.log(better.dtype.kind); // "int" +console.log(better.values); // [1, 2, 3] // Mixed types — cannot infer, returns original const mixed = new Series({ data: [1, "a", true], dtype: Dtype.object }); -inferObjectsSeries(mixed).dtype.kind; // "object" +console.log(inferObjectsSeries(mixed).dtype.kind); // "object" // All null — no inference possible const nulls = new Series({ data: [null, null], dtype: Dtype.object }); -inferObjectsSeries(nulls).dtype.kind; // "object" +console.log(inferObjectsSeries(nulls).dtype.kind); // "object"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -204,10 +204,10 @@

inferObjectsDataFrame — all columns at once

}); const inferred = inferObjectsDataFrame(df); -inferred.col("ints").dtype.kind; // "int" -inferred.col("floats").dtype.kind; // "float" -inferred.col("strs").dtype.kind; // "string" -inferred.col("bools").dtype.kind; // "bool" +console.log(inferred.col("ints").dtype.kind); // "int" +console.log(inferred.col("floats").dtype.kind); // "float" +console.log(inferred.col("strs").dtype.kind); // "string" +console.log(inferred.col("bools").dtype.kind); // "bool"
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -228,21 +228,21 @@

convertDtypesSeries — also parses numeric strings

// String values that look like integers const ints = new Series({ data: ["1", "2", "3"] }); const result = convertDtypesSeries(ints); -result.dtype.kind; // "int" -result.values; // [1, 2, 3] +console.log(result.dtype.kind); // "int" +console.log(result.values); // [1, 2, 3] // String values that look like floats const floats = new Series({ data: ["1.5", "2.5", "3.5"] }); -convertDtypesSeries(floats).dtype.kind; // "float" +console.log(convertDtypesSeries(floats).dtype.kind); // "float" // Non-numeric strings: unchanged const text = new Series({ data: ["apple", "banana"] }); -convertDtypesSeries(text); // same Series, dtype "string" +console.log(convertDtypesSeries(text)); // same Series, dtype "string" // Int series with nulls → can convert to float for NA safety import { Dtype } from "tsb"; const withNull = new Series({ data: [1, null, 3], dtype: Dtype.int64 }); -convertDtypesSeries(withNull, { convertIntegerToFloat: true }).dtype.kind; +console.log(convertDtypesSeries(withNull, { convertIntegerToFloat: true }).dtype.kind); // "float" (null becomes NaN-compatible)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -269,9 +269,9 @@

convertDtypesDataFrame — per-column conversion

}); const typed = convertDtypesDataFrame(raw); -typed.col("age").dtype.kind; // "int" -typed.col("score").dtype.kind; // "float" -typed.col("name").dtype.kind; // "string" (unchanged — not numeric) +console.log(typed.col("age").dtype.kind); // "int" +console.log(typed.col("score").dtype.kind); // "float" +console.log(typed.col("name").dtype.kind); // "string" (unchanged — not numeric)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/insert_pop.html b/playground/insert_pop.html index 5cdfcfb5..ca7b4eb6 100644 --- a/playground/insert_pop.html +++ b/playground/insert_pop.html @@ -175,7 +175,8 @@

Example 1 — insertColumn

// df2.col("city").values → ["NY", "LA", "SF"] // Original is unchanged -// df.columns.values → ["name", "age"] +// df.columns.values → ["name", "age"] +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -197,7 +198,8 @@

Example 2 — Insert with a Series

const salary = new Series({ data: [100_000, 90_000, 120_000], name: "salary" }); const df2 = insertColumn(df, 0, "salary", salary); -// df2.columns.values → ["salary", "a", "b"] +// df2.columns.values → ["salary", "a", "b"] +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -225,7 +227,8 @@

Example 3 — popColumn

const { series: ageSeries, df: df2 } = popColumn(df, "age"); // ageSeries.values → [30, 25, 35] // df2.columns.values → ["id", "name"] -// df.columns.values → ["id", "name", "age"] ← original unchanged +// df.columns.values → ["id", "name", "age"] ← original unchanged +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -251,7 +254,8 @@

Example 4 — reorderColumns

// Select a subset (drops columns not listed) const df3 = reorderColumns(df, ["a", "c"]); -// df3.columns.values → ["a", "c"] (b and d are dropped) +// df3.columns.values → ["a", "c"] (b and d are dropped) +console.log(df3);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -278,7 +282,8 @@

Example 5 — moveColumn

// Move "label" to the front const df2 = moveColumn(df, "label", 0); -// df2.columns.values → ["label", "year", "value"] +// df2.columns.values → ["label", "year", "value"] +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -295,19 +300,19 @@

Error cases

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/interpolate.html b/playground/interpolate.html index e5d2d744..8302847f 100644 --- a/playground/interpolate.html +++ b/playground/interpolate.html @@ -172,7 +172,7 @@

1 · Linear interpolation (default)

// 0 1 2 3 const filled = interpolateSeries(s); -filled.values; +console.log(filled.values); // → [1, 2, 3, 4]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -194,7 +194,7 @@

1 · Linear interpolation (default)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -243,7 +243,7 @@

3 · Backward fill (bfill / backfill)

const s = new Series({ data: [null, 2, null, null, 5] }); -interpolateSeries(s, { method: "bfill" }).values; +console.log(interpolateSeries(s, { method: "bfill" }).values); // → [2, 2, 5, 5, 5]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -270,7 +270,7 @@

4 · Nearest-neighbor

// pos 2: dist-left=2, dist-right=1 → right wins → 4 const s = new Series({ data: [1, null, null, 4] }); -interpolateSeries(s, { method: "nearest" }).values; +console.log(interpolateSeries(s, { method: "nearest" }).values); // → [1, 1, 4, 4]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -292,7 +292,7 @@

4 · Nearest-neighbor

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -318,15 +318,15 @@

5 · Limiting how many values are filled

const s = new Series({ data: [0, null, null, null, 4] }); // limit=1, forward: fill only the first NaN from the left -interpolateSeries(s, { limit: 1 }).values; +console.log(interpolateSeries(s, { limit: 1 }).values); // → [0, 1, null, null, 4] // limit=1, backward: fill only the last NaN from the right -interpolateSeries(s, { limit: 1, limitDirection: "backward" }).values; +console.log(interpolateSeries(s, { limit: 1, limitDirection: "backward" }).values); // → [0, null, null, 3, 4] // limit=1, both: fill one from each end -interpolateSeries(s, { limit: 1, limitDirection: "both" }).values; +console.log(interpolateSeries(s, { limit: 1, limitDirection: "both" }).values); // → [0, 1, null, 3, 4]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -353,8 +353,8 @@

6 · DataFrame — column-wise (axis=0, default)

}); const filled = dataFrameInterpolate(df); -filled.col("temperature").values; // [20, 21, 22, 23] -filled.col("humidity").values; // [60, 65, 70, null] ← trailing not filled +console.log(filled.col("temperature").values); // [20, 21, 22, 23] +console.log(filled.col("humidity").values); // [60, 65, 70, null] ← trailing not filled
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -384,8 +384,8 @@

7 · DataFrame — row-wise (axis=1)

// Row 0 interpolates 0 → 6 (linear, 4 steps) // Row 1 interpolates 10 → 22 const filled = dataFrameInterpolate(df, { axis: 1 }); -filled.col("t1").values; // [2, 14] -filled.col("t2").values; // [4, 18] +console.log(filled.col("t1").values); // [2, 14] +console.log(filled.col("t2").values); // [4, 18]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/join.html b/playground/join.html index 8ee935dc..143352d5 100644 --- a/playground/join.html +++ b/playground/join.html @@ -175,7 +175,7 @@

Left join (default)

{ index: ["alice", "charlie"] }, ); -join(employees, salaries); +console.log(join(employees, salaries)); // dept salary // alice Engineering 90000 // bob Marketing null ← no salary for bob @@ -195,13 +195,13 @@

Inner / outer / right join

-
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -224,7 +224,7 @@

Overlapping columns — use lsuffix / rsuffix

// This would throw — 'score' exists in both without suffix disambiguation: // join(a, b); -join(a, b, { lsuffix: "_a", rsuffix: "_b" }); +console.log(join(a, b, { lsuffix: "_a", rsuffix: "_b" })); // score_a score_b // x 10 15 // y 20 25 @@ -253,7 +253,7 @@

Join on a column key

); // Join orders.customerId against customers index -join(orders, customers, { on: "customerId", how: "left" }); +console.log(join(orders, customers, { on: "customerId", how: "left" })); // customerId amount name // C1 100 Alice // C2 200 Bob @@ -279,7 +279,7 @@

joinAll — chain multiple joins

const b1 = DataFrame.fromColumns({ B: [10,20,30] }, { index: ["K0","K1","K2"] }); const b2 = DataFrame.fromColumns({ C: [100,200,300] }, { index: ["K0","K1","K2"] }); -joinAll(base, [b1, b2]); +console.log(joinAll(base, [b1, b2])); // A B C // 1 10 100 // 2 20 200 @@ -304,7 +304,7 @@

crossJoin — Cartesian product

const colors = DataFrame.fromColumns({ color: ["red", "blue"] }); const sizes = DataFrame.fromColumns({ size: ["S", "M", "L"] }); -crossJoin(colors, sizes); +console.log(crossJoin(colors, sizes)); // color size // red S // red M diff --git a/playground/json_normalize.html b/playground/json_normalize.html index 5820aa06..ccc9a158 100644 --- a/playground/json_normalize.html +++ b/playground/json_normalize.html @@ -172,7 +172,8 @@

Example 1 — flatten nested dicts

const df = jsonNormalize(data); // id info.name info.city // 1 Alice NY -// 2 Bob LA +// 2 Bob LA +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -200,7 +201,8 @@

Example 2 — recordPath + meta

// sku qty orderId customer // X 2 A1 Alice // Y 1 A1 Alice -// Z 5 B2 Bob +// Z 5 B2 Bob +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -218,7 +220,7 @@

Example 3 — maxLevel

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/math_ops.html b/playground/math_ops.html index ba3f3726..232d571d 100644 --- a/playground/math_ops.html +++ b/playground/math_ops.html @@ -168,23 +168,23 @@

Code Examples

// ── absSeries ──────────────────────────────────────────────────────────────── const s = new Series({ data: [-1, 2, -3, null] }); -absSeries(s).values; // [1, 2, 3, null] +console.log(absSeries(s).values); // [1, 2, 3, null] // ── absDataFrame ───────────────────────────────────────────────────────────── const df = DataFrame.fromColumns({ a: [-1, 2], b: [3, -4] }); -absDataFrame(df).col("a").values; // [1, 2] -absDataFrame(df).col("b").values; // [3, 4] +console.log(absDataFrame(df).col("a").values); // [1, 2] +console.log(absDataFrame(df).col("b").values); // [3, 4] // ── roundSeries ────────────────────────────────────────────────────────────── const prices = new Series({ data: [1.234, 5.678, null] }); -roundSeries(prices, 2).values; // [1.23, 5.68, null] -roundSeries(prices, 0).values; // [1, 6, null] -roundSeries(prices, -1).values; // nearest 10: [0, 10, null] +console.log(roundSeries(prices, 2).values); // [1.23, 5.68, null] +console.log(roundSeries(prices, 0).values); // [1, 6, null] +console.log(roundSeries(prices, -1).values); // nearest 10: [0, 10, null] // ── roundDataFrame ──────────────────────────────────────────────────────────── const data = DataFrame.fromColumns({ price: [1.111, 2.222], qty: [3.7, 4.4] }); -roundDataFrame(data, 2).col("price").values; // [1.11, 2.22] -roundDataFrame(data, { price: 1, qty: 0 }).col("qty").values; // [4, 4] +console.log(roundDataFrame(data, 2).col("price").values); // [1.11, 2.22] +console.log(roundDataFrame(data, { price: 1, qty: 0 }).col("qty").values); // [4, 4]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/memory_usage.html b/playground/memory_usage.html index 2956fb1d..faa9e18d 100644 --- a/playground/memory_usage.html +++ b/playground/memory_usage.html @@ -167,8 +167,8 @@

1 · Series memory_usage — fixed-width dtype

+console.log(seriesMemoryUsage(s)); // 40 (data + index) +console.log(seriesMemoryUsage(s, { index: false })); // 16 (data only)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -186,9 +186,9 @@

2 · Series memory_usage — string dtype (shallow vs deep)

+console.log(seriesMemoryUsage(s, { index: false, deep: true })); // "hello"=66, "world"=66, "tsb"=62 → 194
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -214,7 +214,8 @@

3 · DataFrame memory_usage — per-column breakdown

// Index (RangeIndex) → 24 bytes // id (int32 × 3) → 12 bytes // score (float64 × 3)→ 24 bytes -// name (string × 3, shallow) → 24 bytes +// name (string × 3, shallow) → 24 bytes +console.log(mu);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -235,7 +236,8 @@

4 · DataFrame memory_usage — deep=true for string columns

}); dataFrameMemoryUsage(df, { deep: true, index: false }) // "short" → 5*2+56 = 66 -// "a slightly longer string" → 24*2+56 = 104 +// "a slightly longer string" → 24*2+56 = 104 +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -256,7 +258,7 @@

5 · Total memory across all columns

b: new Series({ data: Array.from({length: 1000}, (_,i) => i * 0.1), dtype: Dtype.float64 }), }); const mu = dataFrameMemoryUsage(df, { index: false }); -mu.sum(); // 1000*8 + 1000*8 = 16000 bytes +console.log(mu.sum()); // 1000*8 + 1000*8 = 16000 bytes
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/merge_asof.html b/playground/merge_asof.html index c48b422c..bd015293 100644 --- a/playground/merge_asof.html +++ b/playground/merge_asof.html @@ -179,7 +179,8 @@

Basic example — backward (default)

// time | price | bid // 1 | 100 | null ← no quote ≤ 1 // 5 | 200 | 98 ← most recent quote ≤ 5 is at time=2 -// 10 | 300 | 195 ← most recent quote ≤ 10 is at time=6 +// 10 | 300 | 195 ← most recent quote ≤ 10 is at time=6 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -203,7 +204,8 @@

Forward direction

on: "t", direction: "forward", }); -// t=1 → t=2 (w=20), t=3 → t=6 (w=60), t=7 → t=10 (w=100) +// t=1 → t=2 (w=20), t=3 → t=6 (w=60), t=7 → t=10 (w=100) +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -223,7 +225,8 @@

Nearest direction

on: "time", direction: "nearest", }); -// Picks the quote with the smallest absolute time difference. +// Picks the quote with the smallest absolute time difference. +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -251,7 +254,7 @@

Grouping with by

bid: [99, 198, 109, 208], }); -mergeAsof(trades, quotes, { on: "time", by: "ticker" }); +console.log(mergeAsof(trades, quotes, { on: "time", by: "ticker" }));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -268,7 +271,7 @@

Tolerance

+console.log(mergeAsof(left, right, { on: "t", tolerance: 2 }));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/merge_ordered.html b/playground/merge_ordered.html index 4eb45e76..8f1a2c2f 100644 --- a/playground/merge_ordered.html +++ b/playground/merge_ordered.html @@ -181,7 +181,8 @@

Basic outer ordered merge

// 2 | null | 200 // 3 | 30 | 300 // 5 | 50 | null -// 6 | null | 600 +// 6 | null | 600 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -206,7 +207,8 @@

Forward-fill after merge

// 2 | 10 | 200 ← price carried forward from date=1 // 3 | 30 | 300 // 5 | 50 | 300 ← volume carried forward from date=3 -// 6 | 50 | 600 +// 6 | 50 | 600 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -223,7 +225,7 @@

Inner join variant

Click ▶ Run to execute
@@ -244,7 +246,7 @@

Different key column names per side

+// B | 3 | 300 | 300 +console.log(right3);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -308,7 +311,7 @@

Overlapping non-key columns — suffixes

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -180,7 +180,7 @@

2 · Tied modes — all returned sorted

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -198,7 +198,7 @@

3 · String values

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -216,7 +216,7 @@

4 · Null values excluded (dropna=true default)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -234,7 +234,7 @@

5 · DataFrame column-wise (axis=0)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -252,7 +252,7 @@

6 · DataFrame row-wise (axis=1)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/named_agg.html b/playground/named_agg.html index 62fc72a5..4f3c69ee 100644 --- a/playground/named_agg.html +++ b/playground/named_agg.html @@ -182,7 +182,8 @@

Basic Usage

// result: // | total_salary | avg_salary | employees | avg_score // eng | 330 | 110 | 3 | 4.167 -// hr | 170 | 85 | 2 | 3.5 +// hr | 170 | 85 | 2 | 3.5 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -227,7 +228,8 @@

Custom Aggregation Functions

df.groupby("dept").aggNamed({ salary_range: namedAgg("salary", salaryRange), -}); +}); +console.log(salaryRange);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/nancumops.html b/playground/nancumops.html index 6e9d221a..009058fe 100644 --- a/playground/nancumops.html +++ b/playground/nancumops.html @@ -168,10 +168,10 @@

💡 Usage Examples

const data = [1, 2, NaN, null, 3, 5]; -nansum(data); // 11 -nanmean(data); // 2.75 -nanmedian(data); // 2.5 -nanstd(data); // 1.708... +console.log(nansum(data)); // 11 +console.log(nanmean(data)); // 2.75 +console.log(nanmedian(data)); // 2.5 +console.log(nanstd(data)); // 1.708...
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -192,9 +192,9 @@

💡 Usage Examples

const s = new Series({ data: [10, null, 30, NaN, 50] }); -nancount(s); // 3 -nansum(s); // 90 -nanmean(s); // 30 +console.log(nancount(s)); // 3 +console.log(nansum(s)); // 90 +console.log(nanmean(s)); // 30
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -216,12 +216,12 @@

💡 Usage Examples

const xs = [2, 4, 4, 4, 5, 5, 7, 9]; // Sample (ddof=1, default) -nanvar(xs); // ≈ 4.571 -nanstd(xs); // ≈ 2.138 +console.log(nanvar(xs)); // ≈ 4.571 +console.log(nanstd(xs)); // ≈ 2.138 // Population (ddof=0) -nanvar(xs, { ddof: 0 }); // 4.0 -nanstd(xs, { ddof: 0 }); // 2.0 +console.log(nanvar(xs, { ddof: 0 })); // 4.0 +console.log(nanstd(xs, { ddof: 0 })); // 2.0
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/natsort.html b/playground/natsort.html index 5b2d3e94..a419c55b 100644 --- a/playground/natsort.html +++ b/playground/natsort.html @@ -194,11 +194,11 @@

2 · Options

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -224,7 +224,7 @@

3 · Sorting objects with a key function

// key extracts the string to sort by import { natSorted } from "tsb"; const sorted = natSorted(rows, { key: r => r.path }); -sorted.map(r => r.path); +console.log(sorted.map(r => r.path)); // → ["img/photo1.jpg", "img/photo2.jpg", "img/photo10.jpg"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -243,13 +243,13 @@

4 · natSortKey — inspect the token representation

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -272,7 +272,7 @@

5 · natArgSort — permutation indices

const idx = natArgSort(arr); // → [2, 1, 0] (indices of "file1", "file2", "file10") -idx.map(i => arr[i]); +console.log(idx.map(i => arr[i])); // → ["file1", "file2", "file10"] // Use with a tsb Index to sort labels naturally: @@ -300,7 +300,7 @@

6 · Comparison with lexicographic sort

// → ["item1", "item12", "item2", "item20", "item3"] ← wrong // Natural sort -natSorted(data); +console.log(natSorted(data)); // → ["item1", "item2", "item3", "item12", "item20"] ← correct
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/notna.html b/playground/notna.html index 60910600..719d3aaf 100644 --- a/playground/notna.html +++ b/playground/notna.html @@ -163,18 +163,18 @@

Example 1 — scalars

+console.log(notna(null)); // false +console.log(notna(42)); // true
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -193,10 +193,10 @@

Example 2 — arrays

+console.log(isnull(null)); // true +console.log(notnull("hello")); // true
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/notna_boolean.html b/playground/notna_boolean.html index 79141124..e7486bf4 100644 --- a/playground/notna_boolean.html +++ b/playground/notna_boolean.html @@ -167,10 +167,10 @@

Code Examples

const s = new Series({ data: [10, 20, 30, 40], index: ["a", "b", "c", "d"] }); // Keep elements where mask is true -keepTrue(s, [true, false, true, false]).values; // [10, 30] +console.log(keepTrue(s, [true, false, true, false]).values); // [10, 30] // Keep elements where mask is false (complement) -keepFalse(s, [true, false, true, false]).values; // [20, 40] +console.log(keepFalse(s, [true, false, true, false]).values); // [20, 40] // Filter DataFrame rows const df = DataFrame.fromColumns( @@ -178,11 +178,11 @@

Code Examples

{ index: ["alice", "bob", "carol", "dave"] }, ); const highScore = df.col("score").values.map((v) => (v as number) >= 80); -filterBy(df, highScore).col("age").values; // [25, 35] +console.log(filterBy(df, highScore).col("age").values); // [25, 35] // Use a Series as a mask const mask = new Series({ data: [true, null, true, false], index: ["a", "b", "c", "d"] }); -keepTrue(s, mask).values; // [10, 30] (null treated as false) +console.log(keepTrue(s, mask).values); // [10, 30] (null treated as false)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/notna_isna.html b/playground/notna_isna.html index 7f73051e..b58c30c8 100644 --- a/playground/notna_isna.html +++ b/playground/notna_isna.html @@ -166,49 +166,49 @@

📝 Code examples

import { Series, DataFrame } from "tsb"; // ── scalar ────────────────────────────────────────────────── -isna(null); // true -isna(undefined); // true -isna(NaN); // true -isna(0); // false — zero is not missing -isna(false); // false — false is not missing -isna(""); // false — empty string is not missing +console.log(isna(null)); // true +console.log(isna(undefined)); // true +console.log(isna(NaN)); // true +console.log(isna(0)); // false — zero is not missing +console.log(isna(false)); // false — false is not missing +console.log(isna("")); // false — empty string is not missing // ── array ─────────────────────────────────────────────────── -isna([1, null, NaN, 3]); // [false, true, true, false] -notna([1, null, NaN, 3]); // [true, false, false, true] +console.log(isna([1, null, NaN, 3])); // [false, true, true, false] +console.log(notna([1, null, NaN, 3])); // [true, false, false, true] // ── Series ────────────────────────────────────────────────── const s = new Series({ data: [1, null, NaN, 4] }); -isna(s).values; // [false, true, true, false] -notna(s).values; // [true, false, false, true] +console.log(isna(s).values); // [false, true, true, false] +console.log(notna(s).values); // [true, false, false, true] // ── DataFrame ─────────────────────────────────────────────── const df = new DataFrame(new Map([ ["a", new Series({ data: [1, null, 3] })], ["b", new Series({ data: [NaN, 5, 6] })], ])); -isna(df).col("a").values; // [false, true, false] -isna(df).col("b").values; // [true, false, false] +console.log(isna(df).col("a").values); // [false, true, false] +console.log(isna(df).col("b").values); // [true, false, false] // ── aliases ───────────────────────────────────────────────── -isnull(null); // true (same as isna) -notnull(42); // true (same as notna) +console.log(isnull(null)); // true (same as isna) +console.log(notnull(42)); // true (same as notna) // ── fillna ────────────────────────────────────────────────── -fillna([1, null, NaN, 4], { value: 0 }); // [1, 0, 0, 4] -fillna(s, { value: -1 }).values; // [1, -1, -1, 4] -fillna(df, { value: 0 }).col("b").values; // [0, 5, 6] +console.log(fillna([1, null, NaN, 4], { value: 0 })); // [1, 0, 0, 4] +console.log(fillna(s, { value: -1 }).values); // [1, -1, -1, 4] +console.log(fillna(df, { value: 0 }).col("b").values); // [0, 5, 6] // ── dropna ────────────────────────────────────────────────── -dropna([1, null, NaN, 3]); // [1, 3] -dropna(s).values; // [1, 4] -dropna(df).shape; // [2, 2] (row 0 dropped because b[0]=NaN, row 1 dropped because a[1]=null) -dropna(df, { how: "all" }).shape; // drops only rows where ALL values are missing -dropna(df, { axis: 1 }).columns.values; // drops columns that contain any missing value +console.log(dropna([1, null, NaN, 3])); // [1, 3] +console.log(dropna(s).values); // [1, 4] +console.log(dropna(df).shape); // [2, 2] (row 0 dropped because b[0]=NaN, row 1 dropped because a[1]=null) +console.log(dropna(df, { how: "all" }).shape); // drops only rows where ALL values are missing +console.log(dropna(df, { axis: 1 }).columns.values); // drops columns that contain any missing value // ── countna / countValid ───────────────────────────────────── -countna([1, null, NaN, 3]); // 2 -countValid([1, null, NaN, 3]); // 2 +console.log(countna([1, null, NaN, 3])); // 2 +console.log(countValid([1, null, NaN, 3])); // 2
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/numeric_extended.html b/playground/numeric_extended.html index a399d8ad..d92ec244 100644 --- a/playground/numeric_extended.html +++ b/playground/numeric_extended.html @@ -179,7 +179,7 @@

digitize — bin values

// Series version — preserves index const s = new Series({ data: [15, 45, 70], index: ["Alice","Bob","Carol"] }); -seriesDigitize(s, [33, 66, 100]); +console.log(seriesDigitize(s, [33, 66, 100])); // Series: Alice→-1, Bob→1, Carol→2
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -208,7 +208,7 @@

histogram — frequency counts

const { counts: d, binEdges: e } = histogram(data, { bins: 5, density: true }); // Explicit edges -histogram(data, { binEdges: [1, 4, 7, 10] }); +console.log(histogram(data, { binEdges: [1, 4, 7, 10] })); // counts: [ 3, 3, 4 ]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -229,19 +229,19 @@

linspace & arange — number sequences

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -265,9 +265,9 @@

percentileOfScore — percentile rank

const grades = [55, 60, 70, 75, 80, 85, 90, 95]; // What percentile is a score of 75? -percentileOfScore(grades, 75); // 50 (rank — default) -percentileOfScore(grades, 75, "weak"); // 50 (≤ 75: 4/8 = 50%) -percentileOfScore(grades, 75, "strict"); // 37.5 (< 75: 3/8 = 37.5%) +console.log(percentileOfScore(grades, 75)); // 50 (rank — default) +console.log(percentileOfScore(grades, 75, "weak")); // 50 (≤ 75: 4/8 = 50%) +console.log(percentileOfScore(grades, 75, "strict")); // 37.5 (< 75: 3/8 = 37.5%)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -293,7 +293,8 @@

zscore — standardisation

// z.values ≈ [-1.5, -0.5, -0.5, -0.5, 0, 0, 1, 2] // With population std (ddof=0) -const zPop = zscore(s, { ddof: 0 }); +const zPop = zscore(s, { ddof: 0 }); +console.log(zPop);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -314,11 +315,11 @@

minMaxNormalize — scale to [0, 1]

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -340,13 +341,13 @@

coefficientOfVariation — relative spread

+console.log(coefficientOfVariation(new Series({ data: [1, 2, 3, 4, 5] }), { ddof: 0 }));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/nunique.html b/playground/nunique.html index 77c6fa17..8b7d4e8a 100644 --- a/playground/nunique.html +++ b/playground/nunique.html @@ -165,8 +165,8 @@

1 · nunique — count distinct values

const s = new Series({ data: [1, 2, 2, 3, 3, 3, null] }); -nuniqueSeries(s); // 3 (null excluded by default) -nuniqueSeries(s, { dropna: false }); // 4 (null counted as a distinct value) +console.log(nuniqueSeries(s)); // 3 (null excluded by default) +console.log(nuniqueSeries(s, { dropna: false })); // 4 (null counted as a distinct value)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -187,12 +187,12 @@

2 · any — is any element truthy?

const allZero = new Series({ data: [0, 0, 0] }); const hasOne = new Series({ data: [0, 0, 1] }); -anySeries(allZero); // false -anySeries(hasOne); // true +console.log(anySeries(allZero)); // false +console.log(anySeries(hasOne)); // true // With nulls (skipna=true by default) const withNull = new Series({ data: [null, 0, null] }); -anySeries(withNull); // false — null skipped, 0 is falsy +console.log(anySeries(withNull)); // false — null skipped, 0 is falsy
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -213,12 +213,12 @@

3 · all — are all elements truthy?

const allTrue = new Series({ data: [1, 2, 3] }); const hasFalsy = new Series({ data: [1, 0, 3] }); -allSeries(allTrue); // true -allSeries(hasFalsy); // false +console.log(allSeries(allTrue)); // true +console.log(allSeries(hasFalsy)); // false // Empty or all-null series vacuously returns true -allSeries(new Series({ data: [] })); // true -allSeries(new Series({ data: [null, null] })); // true +console.log(allSeries(new Series({ data: [] }))); // true +console.log(allSeries(new Series({ data: [null, null] }))); // true
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -241,8 +241,8 @@

4 · DataFrame nunique

value: [1, 2, 1, 3 ], }); -nuniqueDataFrame(df); // per-column: category→3, value→3 -nuniqueDataFrame(df, { axis: 1 }); // per-row: how many distinct values in each row +console.log(nuniqueDataFrame(df)); // per-column: category→3, value→3 +console.log(nuniqueDataFrame(df, { axis: 1 })); // per-row: how many distinct values in each row
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -265,12 +265,12 @@

5 · DataFrame any / all

b: [1, 1, 1], }); -anyDataFrame(df2); // a: true, b: true (each col has at least one truthy) -allDataFrame(df2); // a: false, b: true (col a has a 0) +console.log(anyDataFrame(df2)); // a: true, b: true (each col has at least one truthy) +console.log(allDataFrame(df2)); // a: false, b: true (col a has a 0) // axis=1: reduce across columns per row -anyDataFrame(df2, { axis: 1 }); // row0: true, row1: true, row2: true -allDataFrame(df2, { axis: 1 }); // row0: false, row1: false, row2: true +console.log(anyDataFrame(df2, { axis: 1 })); // row0: true, row1: true, row2: true +console.log(allDataFrame(df2, { axis: 1 })); // row0: false, row1: false, row2: true
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/pipe_apply.html b/playground/pipe_apply.html index 4a26f5bc..d6d2fa50 100644 --- a/playground/pipe_apply.html +++ b/playground/pipe_apply.html @@ -180,7 +180,8 @@

pipe — functional pipeline

(x) => x * x, // 16 (x) => x - 1, // 15 ); -// n === 15 +// n === 15 +console.log(n);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -214,7 +215,8 @@

seriesApply — element-wise apply

new Series({ data: [10, 20, 30] }), (v, _label, pos) => (v as number) + pos * 100, ); -// [10, 120, 230] +// [10, 120, 230] +console.log(withPos);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -249,7 +251,8 @@

dataFrameApply — column/row aggregation

(row) => (row.at("score") as number) * (row.at("weight") as number), 1, ); -// [85, 110.4, 62.4, 142.5] +// [85, 110.4, 62.4, 142.5] +console.log(weightedScore);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -283,7 +286,8 @@

dataFrameApplyMap — element-wise cell transform

// fn receives full context: (value, rowLabel, colName) const tagged = dataFrameApplyMap(df, (v, row, col) => `${col}[${row}]=${v}`); // a: ["a[0]=1", "a[1]=-2", "a[2]=3"] -// b: ["b[0]=-4", "b[1]=5", "b[2]=-6"] +// b: ["b[0]=-4", "b[1]=5", "b[2]=-6"] +console.log(tagged);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -328,7 +332,8 @@

dataFrameTransform — column-wise transform

if (n <= q3) return "Q3"; return "Q4"; }); -}); +}); +console.log(binned);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -367,7 +372,8 @@

dataFrameTransformRows — row-wise transform

last: row["last"], score: row["score"], full: `${row["first"]} ${row["last"]}`, -})); +})); +console.log(withFull);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -408,7 +414,8 @@

Combining pipe + apply

typeof v === "number" ? Math.round(v * 100) / 100 : v ) ), -); +); +console.log(clean);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/pivot_table.html b/playground/pivot_table.html index 74be448f..66ec2b94 100644 --- a/playground/pivot_table.html +++ b/playground/pivot_table.html @@ -181,7 +181,8 @@

Example 1 — sales by region and product (sum + margins)

// A B All // North 220 200 420 // South 150 430 580 -// All 370 630 1000 +// All 370 630 1000 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -216,7 +217,8 @@

Example 2 — mean aggregation with custom margins_name

// Jr Sr Total // Eng 70 90 80 // Mkt 60 80 70 -// Total 65 85 75 +// Total 65 85 75 +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -247,7 +249,8 @@

Example 3 — sort=false preserves insertion order

}); // Rows in order: Z, A, M (insertion order) -// Cols in order: b, a, c (insertion order) +// Cols in order: b, a, c (insertion order) +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -280,7 +283,8 @@

Example 4 — count with margins

// Jr Sr All // Eng 1 2 3 // Mkt 1 1 2 -// All 2 3 5 +// All 2 3 5 +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/quantile.html b/playground/quantile.html index 49c30941..849f0030 100644 --- a/playground/quantile.html +++ b/playground/quantile.html @@ -162,9 +162,9 @@

1 · Scalar quantile (median)

+console.log(quantileSeries(s)); // default q=0.5 → 3 +console.log(quantileSeries(s, { q: 0.25 })); // → 2 +console.log(quantileSeries(s, { q: 0.75 })); // → 4
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -182,7 +182,8 @@

2 · Multiple quantile levels

+// Series indexed by q-values: { 0.25: 2, 0.5: 3, 0.75: 4 } +console.log(q);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -200,11 +201,11 @@

3 · Interpolation methods

+console.log(quantileSeries(s, { q: 0.5, interpolation: "linear" })); // 5 +console.log(quantileSeries(s, { q: 0.5, interpolation: "lower" })); // 0 +console.log(quantileSeries(s, { q: 0.5, interpolation: "higher" })); // 10 +console.log(quantileSeries(s, { q: 0.5, interpolation: "midpoint" })); // 5 +console.log(quantileSeries(s, { q: 0.5, interpolation: "nearest" })); // 0
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -221,8 +222,8 @@

4 · NaN handling (skipna=true by default)

+console.log(quantileSeries(s, { q: 0.5 })); // ignores null/NaN → 3 +console.log(quantileSeries(s, { q: 0.5, skipna: false })); // NaN propagates → NaN
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -239,10 +240,10 @@

5 · DataFrame — axis=0 (per-column quantiles)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -260,7 +261,7 @@

6 · DataFrame — axis=1 (per-row quantiles)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -278,7 +279,7 @@

7 · Q=[0, 0.25, 0.5, 0.75, 1] summary table

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/reduce_ops.html b/playground/reduce_ops.html index 993ae52c..8f481400 100644 --- a/playground/reduce_ops.html +++ b/playground/reduce_ops.html @@ -169,8 +169,8 @@

nuniqueSeries — count distinct values

+console.log(nuniqueSeries(s)); // 3 (null excluded by default) +console.log(nuniqueSeries(s, { dropna: false })); // 4 (null counted as a distinct value)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -193,7 +193,7 @@

nunique — count distinct per column (axis=0, default)

rating: [5, 3, 5, 4], flag: [true, false, true, null], }); -nunique(df); +console.log(nunique(df)); // Series { brand: 3, rating: 3, flag: 2 }
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -210,7 +210,7 @@

nunique — count distinct per row (axis=1)

-
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -230,16 +230,16 @@

anySeries / allSeries

+console.log(allSeries(withNull)); // true (null skipped) +console.log(allSeries(withNull, { skipna: false })); // false (null is falsy)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -263,14 +263,14 @@

anyDataFrame / allDataFrame

c: [0, 0, 0], }); -anyDataFrame(df2); +console.log(anyDataFrame(df2)); // Series { a: true, b: true, c: false } -allDataFrame(df2); +console.log(allDataFrame(df2)); // Series { a: false, b: true, c: false } // axis=1: reduce across columns → one boolean per row -anyDataFrame(df2, { axis: 1 }); +console.log(anyDataFrame(df2, { axis: 1 })); // Series [true, true, true] (row 0: 0,1,0 → any=true via b)
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -293,7 +293,7 @@

boolOnly option

}); // Only consider boolean columns -anyDataFrame(mixed, { boolOnly: true }); +console.log(anyDataFrame(mixed, { boolOnly: true })); // Series { flag: true } — 'nums' column excluded
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/reindex.html b/playground/reindex.html index ac05172c..6e4860aa 100644 --- a/playground/reindex.html +++ b/playground/reindex.html @@ -166,19 +166,19 @@

1 · reindexSeries — basics

const s = new Series({ data: [10, 20, 30], index: new Index(["a", "b", "c"]) }); // Reorder labels -reindexSeries(s, ["c", "a", "b"]).toArray(); +console.log(reindexSeries(s, ["c", "a", "b"]).toArray()); // → [30, 10, 20] // Extend with new labels → null by default -reindexSeries(s, ["a", "b", "c", "d"]).toArray(); +console.log(reindexSeries(s, ["a", "b", "c", "d"]).toArray()); // → [10, 20, 30, null] // Extend with custom fill value -reindexSeries(s, ["a", "b", "c", "d"], { fillValue: 0 }).toArray(); +console.log(reindexSeries(s, ["a", "b", "c", "d"], { fillValue: 0 }).toArray()); // → [10, 20, 30, 0] // Drop labels -reindexSeries(s, ["a", "c"]).toArray(); +console.log(reindexSeries(s, ["a", "c"]).toArray()); // → [10, 30]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -203,21 +203,21 @@

2 · Fill methods

}); // Forward fill — carry last known value forward -reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "ffill" }).toArray(); +console.log(reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "ffill" }).toArray()); // → [15, 15, 18, 18, 18, 22] // ^^ ^^ ^^ ← filled from left // Backward fill — carry next known value backward -reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "bfill" }).toArray(); +console.log(reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "bfill" }).toArray()); // → [15, 18, 18, 22, 22, 22] // ^^ ^^ ^^ ← filled from right // Nearest — use closest value (prefer right on tie) -reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "nearest" }).toArray(); +console.log(reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "nearest" }).toArray()); // → [15, 15, 18, 18, 22, 22] // Limit — cap consecutive fills -reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "ffill", limit: 1 }).toArray(); +console.log(reindexSeries(temps, [0, 1, 2, 3, 4, 5], { method: "ffill", limit: 1 }).toArray()); // → [15, 15, 18, null, null, 22] // ^^ ^^ only 1 consecutive fill
Click ▶ Run to execute
@@ -244,11 +244,11 @@

3 · reindexDataFrame — rows

// shape [3, 2], RangeIndex [0, 1, 2] // Extend to 5 rows — new rows filled with null -reindexDataFrame(df, { index: [0, 1, 2, 3, 4] }).col("open").toArray(); +console.log(reindexDataFrame(df, { index: [0, 1, 2, 3, 4] }).col("open").toArray()); // → [100, 102, 105, null, null] // Forward-fill new rows -reindexDataFrame(df, { index: [0, 1, 2, 3, 4], method: "ffill" }).col("open").toArray(); +console.log(reindexDataFrame(df, { index: [0, 1, 2, 3, 4], method: "ffill" }).col("open").toArray()); // → [100, 102, 105, 105, 105]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -270,12 +270,12 @@

4 · reindexDataFrame — columns

const df = DataFrame.fromColumns({ a: [1, 2, 3], b: [4, 5, 6] }); // Reorder columns -reindexDataFrame(df, { columns: ["b", "a"] }).columns.toArray(); +console.log(reindexDataFrame(df, { columns: ["b", "a"] }).columns.toArray()); // → ["b", "a"] // Add a new column filled with 0 const r = reindexDataFrame(df, { columns: ["a", "b", "c"], fillValue: 0 }); -r.col("c").toArray(); +console.log(r.col("c").toArray()); // → [0, 0, 0]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -305,8 +305,8 @@

5 · Reindex rows and columns simultaneously

fillValue: -1, }); // shape [4, 3] -r.col("z").toArray(); // → [-1, -1, -1, -1] -r.col("x").toArray(); // → [1, 2, 3, -1] +console.log(r.col("z").toArray()); // → [-1, -1, -1, -1] +console.log(r.col("x").toArray()); // → [1, 2, 3, -1]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/rename_ops.html b/playground/rename_ops.html index 8dbf1ad5..2317026b 100644 --- a/playground/rename_ops.html +++ b/playground/rename_ops.html @@ -177,37 +177,37 @@

Code Examples

const s = new Series({ data: [1, 2, 3], index: ["a", "b", "c"] }); // Record mapping — only matched labels are changed -renameSeriesIndex(s, { a: "x", c: "z" }).index.values; // ["x", "b", "z"] +console.log(renameSeriesIndex(s, { a: "x", c: "z" }).index.values); // ["x", "b", "z"] // Function mapper — called for every index label -renameSeriesIndex(s, l => l.toUpperCase()).index.values; // ["A", "B", "C"] +console.log(renameSeriesIndex(s, l => l.toUpperCase()).index.values); // ["A", "B", "C"] // ── renameDataFrame ────────────────────────────────────────────────────────── const df = DataFrame.fromColumns({ a: [1, 2], b: [3, 4] }, { index: ["r0", "r1"] }); // Rename columns -renameDataFrame(df, { columns: { a: "x", b: "y" } }).columns.values; // ["x","y"] +console.log(renameDataFrame(df, { columns: { a: "x", b: "y" } }).columns.values); // ["x","y"] // Rename row index -renameDataFrame(df, { index: { r0: "row0", r1: "row1" } }).index.values; +console.log(renameDataFrame(df, { index: { r0: "row0", r1: "row1" } }).index.values); // ── add_prefix / add_suffix ────────────────────────────────────────────────── -addPrefixDataFrame(df, "col_").columns.values; // ["col_a","col_b"] -addSuffixDataFrame(df, "_v1").columns.values; // ["a_v1","b_v1"] +console.log(addPrefixDataFrame(df, "col_").columns.values); // ["col_a","col_b"] +console.log(addSuffixDataFrame(df, "_v1").columns.values); // ["a_v1","b_v1"] -addPrefixSeries(s, "idx_").index.values; // ["idx_a","idx_b","idx_c"] -addSuffixSeries(s, "_end").index.values; // ["a_end","b_end","c_end"] +console.log(addPrefixSeries(s, "idx_").index.values); // ["idx_a","idx_b","idx_c"] +console.log(addSuffixSeries(s, "_end").index.values); // ["a_end","b_end","c_end"] // ── set_axis ───────────────────────────────────────────────────────────────── -setAxisSeries(s, ["x", "y", "z"]).index.values; // ["x","y","z"] -setAxisDataFrame(df, ["col1","col2"], 1).columns.values; // ["col1","col2"] -setAxisDataFrame(df, ["rowA","rowB"], 0).index.values; // ["rowA","rowB"] +console.log(setAxisSeries(s, ["x", "y", "z"]).index.values); // ["x","y","z"] +console.log(setAxisDataFrame(df, ["col1","col2"], 1).columns.values); // ["col1","col2"] +console.log(setAxisDataFrame(df, ["rowA","rowB"], 0).index.values); // ["rowA","rowB"] // ── to_frame ───────────────────────────────────────────────────────────────── const score = new Series({ data: [90, 80, 70], name: "score" }); -seriesToFrame(score).columns.values; // ["score"] -seriesToFrame(score, "points").columns.values; // ["points"] +console.log(seriesToFrame(score).columns.values); // ["score"] +console.log(seriesToFrame(score, "points").columns.values); // ["points"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/rolling_apply.html b/playground/rolling_apply.html index ecfcac0a..ff99fed7 100644 --- a/playground/rolling_apply.html +++ b/playground/rolling_apply.html @@ -179,7 +179,7 @@

1. rollingApply — Custom Function Per Window

// Custom: range (max - min) over each 3-day window const range = (w) => Math.max(...w) - Math.min(...w); -rollingApply(prices, 3, range).toArray(); +console.log(rollingApply(prices, 3, range).toArray()); // [null, null, 2, 4, 4, 5] // ↑↑ insufficient data (need 3 observations)
Click ▶ Run to execute
@@ -198,11 +198,11 @@

Options

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -235,7 +235,8 @@

2. rollingAgg — Multiple Aggregations at Once

// result is a DataFrame with columns: "mean", "max", "min", "range" // result.col("mean").toArray() → [null, null, 2, 3, 4, 5, 6, 7] -// result.col("range").toArray() → [null, null, 2, 2, 2, 2, 2, 2] +// result.col("range").toArray() → [null, null, 2, 2, 2, 2, 2, 2] +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -263,7 +264,7 @@

3. dataFrameRollingApply — Apply Per Column

// Pairwise range within each 2-step window per column const range = (w) => Math.max(...w) - Math.min(...w); -dataFrameRollingApply(df, 2, range); +console.log(dataFrameRollingApply(df, 2, range)); // open close // 0 null null // 1 2 2 @@ -304,7 +305,8 @@

4. dataFrameRollingAgg — Multi-Agg Per Column

// A_sum: [null, null, 6, 9, 12] // A_mean: [null, null, 2, 3, 4] // B_sum: [null, null, 60, 90, 120] -// B_mean: [null, null, 20, 30, 40] +// B_mean: [null, null, 20, 30, 40] +console.log(out);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -342,7 +344,8 @@

Use case: Bollinger Band width

const mean = stats.col("mean").toArray()[i]; if (std === null || mean === null || mean === 0) return null; return (4 * (std as number)) / (mean as number); -}); +}); +console.log(bw);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/scalar_extract.html b/playground/scalar_extract.html index 3f1554ca..bf8bbc13 100644 --- a/playground/scalar_extract.html +++ b/playground/scalar_extract.html @@ -190,8 +190,8 @@

squeezeSeries — extract scalar from a single-element Series

+console.log(squeezeSeries(new Series({ data: [42] }))); // 42 +console.log(squeezeSeries(new Series({ data: [1, 2, 3] }))); // Series([1, 2, 3])
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -238,16 +238,16 @@

squeezeDataFrame — squeeze 1-D axis objects

+console.log(squeezeDataFrame(DataFrame.fromColumns({ A: [1, 2, 3] }), 1)); // Series([1, 2, 3])
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -289,8 +289,8 @@

itemSeries — return the single element of a Series

+console.log(itemSeries(new Series({ data: [7] }))); // 7 +console.log(itemSeries(new Series({ data: [1, 2] }))); // throws RangeError
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -330,10 +330,10 @@

boolSeries / boolDataFrame — convert to boolean

+console.log(boolSeries(new Series({ data: [1] }))); // true +console.log(boolSeries(new Series({ data: [0] }))); // false +console.log(boolDataFrame(DataFrame.fromColumns({ A: [1] }))); // true +console.log(boolDataFrame(DataFrame.fromColumns({ A: [false] }))); // false
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -378,11 +378,11 @@

firstValidIndex / lastValidIndex — find first/last non-NA label

+console.log(firstValidIndex(allNA)); // null
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -427,8 +427,8 @@

dataFrameFirstValidIndex / dataFrameLastValidIndex

A: [null, null, 1], B: [null, 2, 3], }); -dataFrameFirstValidIndex(df); // 1 -dataFrameLastValidIndex(df); // 2 +console.log(dataFrameFirstValidIndex(df)); // 1 +console.log(dataFrameLastValidIndex(df)); // 2
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/select_dtypes.html b/playground/select_dtypes.html index 1aebc52c..8c172170 100644 --- a/playground/select_dtypes.html +++ b/playground/select_dtypes.html @@ -253,7 +253,8 @@

6 · Interactive: try your own

z: ["a", "b", "c"], }); const result = selectDtypes(df, { include: "number" }); -return result.columns.toArray().join(", "); +return result.columns.toArray().join(", "); +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/sem_var.html b/playground/sem_var.html index 521c67b8..7dfbd2d4 100644 --- a/playground/sem_var.html +++ b/playground/sem_var.html @@ -165,7 +165,8 @@

1 · Sample variance (ddof=1)

const s = new Series({ data: [2, 4, 4, 4, 5, 5, 7, 9] }); varSeries(s); // 4.0 (sample variance, ddof=1) -varSeries(s, { ddof: 0 }); // 3.5 (population variance, ddof=0) +varSeries(s, { ddof: 0 }); // 3.5 (population variance, ddof=0) +console.log(s);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -184,7 +185,7 @@

2 · Standard error of the mean

+console.log(semSeries(s)); // sqrt(4 / 8) ≈ 0.7071
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -204,7 +205,8 @@

3 · Handling missing values

varSeries(s2); // skipna=true (default): ignores null varSeries(s2, { skipna: false }); // propagates NaN when null present -varSeries(s2, { minCount: 5 }); // NaN: need 5 valid values but only 4 +varSeries(s2, { minCount: 5 }); // NaN: need 5 valid values but only 4 +console.log(s2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -228,7 +230,7 @@

4 · DataFrame column-wise variance

}); varDataFrame(df); // Series { a: 1, b: 100 } -semDataFrame(df); // Series { a: sqrt(1/3), b: sqrt(100/3) } +console.log(semDataFrame(df)); // Series { a: sqrt(1/3), b: sqrt(100/3) } varDataFrame(df, { axis: 1 }); // row-wise variance
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -251,7 +253,8 @@

5 · numericOnly — skip non-numeric columns

}); varDataFrame(df2, { numericOnly: true }); -// Only includes "score", excludes "label" +// Only includes "score", excludes "label" +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/skew_kurt.html b/playground/skew_kurt.html index 3157da85..d326c945 100644 --- a/playground/skew_kurt.html +++ b/playground/skew_kurt.html @@ -162,7 +162,7 @@

1 · Symmetric distribution — skew ≈ 0

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -180,7 +180,7 @@

2 · Right-skewed distribution — positive skew

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -198,7 +198,7 @@

3 · Kurtosis — uniform-like (platykurtic, negative excess)

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -215,8 +215,8 @@

4 · NaN propagation — too few values

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -236,7 +236,7 @@

5 · DataFrame column-wise skewness

symmetric: [1, 2, 3, 4, 5], right_skew: [1, 2, 3, 4, 100], }); -skewDataFrame(df).values; +console.log(skewDataFrame(df).values);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -255,7 +255,7 @@

6 · DataFrame row-wise kurtosis

+console.log(kurtDataFrame(df, { axis: 1 }).values);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/sort_ops.html b/playground/sort_ops.html index 9c9ba9f4..1d5ed930 100644 --- a/playground/sort_ops.html +++ b/playground/sort_ops.html @@ -194,9 +194,9 @@

sortValuesSeries — sort a Series by its values

const s = new Series({ data: [3, 1, 2], index: ["b", "a", "c"] }); -sortValuesSeries(s); // [1, 2, 3] index: ["a","c","b"] -sortValuesSeries(s, { ascending: false }); // [3, 2, 1] index: ["b","c","a"] -sortValuesSeries(s, { ignoreIndex: true }); // resets index to [0, 1, 2] +console.log(sortValuesSeries(s)); // [1, 2, 3] index: ["a","c","b"] +console.log(sortValuesSeries(s, { ascending: false })); // [3, 2, 1] index: ["b","c","a"] +console.log(sortValuesSeries(s, { ignoreIndex: true })); // resets index to [0, 1, 2]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -233,8 +233,8 @@

NaN / null handling

+console.log(sortValuesSeries(s2)); // [1, 3, null] +console.log(sortValuesSeries(s2, { naPosition: "first" })); // [null, 1, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -271,7 +271,7 @@

sortIndexSeries — sort a Series by its index labels

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -317,10 +317,10 @@

sortValuesDataFrame — sort DataFrame rows by column values

const df = DataFrame.fromColumns({ a: [3, 1, 2], b: [10, 30, 20] }); -sortValuesDataFrame(df, "a"); +console.log(sortValuesDataFrame(df, "a")); // col a: [1, 2, 3] col b: [30, 20, 10] -sortValuesDataFrame(df, ["a", "b"], { ascending: [true, false] }); +console.log(sortValuesDataFrame(df, ["a", "b"], { ascending: [true, false] })); // compound sort: by a ascending, then b descending
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -359,11 +359,11 @@

sortIndexDataFrame — sort DataFrame rows (or columns) by index

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/str_findall_and_json_denormalize.html b/playground/str_findall_and_json_denormalize.html index a8a9e94e..a8a2e70c 100644 --- a/playground/str_findall_and_json_denormalize.html +++ b/playground/str_findall_and_json_denormalize.html @@ -183,8 +183,8 @@

1. strFindall — all regex matches per element

// ] // Parse the JSON to get actual arrays: -JSON.parse(allPrices.values[0]); // ["$10.99", "$5.00"] -JSON.parse(allPrices.values[1]); // [] +console.log(JSON.parse(allPrices.values[0])); // ["$10.99", "$5.00"] +console.log(JSON.parse(allPrices.values[1])); // []
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -205,7 +205,8 @@

With capture groups

const names = strFindall(s, /name: (\w+)/); // Series ['["Alice"]', '["Bob"]', '[]'] -// First capture group is extracted (pandas behaviour) +// First capture group is extracted (pandas behaviour) +console.log(names);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -224,7 +225,8 @@

Null / NaN handling

+// Null/NaN elements return null (not []) — matches pandas +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -248,7 +250,7 @@

2. strFindallCount — count matches per element

// Count vowels per word const vowels = new Series({ data: ['beautiful', 'rhythm', 'aeiou'] }); -strFindallCount(vowels, /[aeiou]/i); +console.log(strFindallCount(vowels, /[aeiou]/i)); // Series [5, 0, 5]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -278,7 +280,8 @@

3. strFindFirst — first match per element

// Extract just the year (first capture group) const years = strFindFirst(logs, /(\d{4})-\d{2}-\d{2}/); -// Series ['2024', '2024', null] +// Series ['2024', '2024', null] +console.log(years);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -311,7 +314,8 @@

4. strFindallExpand — expand capture groups into a DataFrame

// 0 1 // 0 John 30 // 1 Jane 25 -// 2 null null +// 2 null null +console.log(df2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -354,7 +358,8 @@

5. toJsonDenormalize — flat DataFrame → nested JSON

]; const df = jsonNormalize(original); const recovered = toJsonDenormalize(df); -// recovered ≈ original (with the same structure) +// recovered ≈ original (with the same structure) +console.log(recovered);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -375,7 +380,7 @@

Custom separator

'user__name': ['Alice'], 'user__city': ['NYC'], }); -toJsonDenormalize(df2, { sep: '__' }); +console.log(toJsonDenormalize(df2, { sep: '__' })); // [{ user: { name: 'Alice', city: 'NYC' } }]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -393,7 +398,7 @@

Drop null values

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -412,7 +417,7 @@

toJsonRecords — orient="records"

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -430,10 +435,10 @@

toJsonSplit — orient="split"

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -451,7 +456,7 @@

toJsonIndex — orient="index"

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/style.html b/playground/style.html index c7ff9071..5afd7a6c 100644 --- a/playground/style.html +++ b/playground/style.html @@ -183,7 +183,8 @@

Overview

.setTableStyles([ { selector: "th", props: { "background-color": "#343a40", color: "#fff" } }, ]) - .toHtml(); + .toHtml(); +console.log(html);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -235,7 +236,8 @@

Factory function

+// Equivalent to: df.style (in pandas) +console.log(styler);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -252,10 +254,10 @@

.format(formatter, subset?, naRep?)

+console.log(dataFrameStyle(df).format(null));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -281,7 +283,7 @@

.formatIndex(formatter)

+console.log(dataFrameStyle(df).formatIndex((v) => `[${String(v)}]`));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -298,7 +300,7 @@

.setPrecision(n)

+console.log(dataFrameStyle(df).setPrecision(2));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -315,7 +317,7 @@

.setNaRep(str)

+console.log(dataFrameStyle(df).setNaRep("N/A"));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -342,8 +344,8 @@

.apply(fn, axis?, subset?)

); // String axis aliases -dataFrameStyle(df).apply(fn, "index"); // same as axis=0 -dataFrameStyle(df).apply(fn, "columns"); // same as axis=1 +console.log(dataFrameStyle(df).apply(fn, "index")); // same as axis=0 +console.log(dataFrameStyle(df).apply(fn, "columns")); // same as axis=1
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -365,7 +367,7 @@

.applymap(fn, subset?) / .map(fn, subset?)

); // .map() is an alias -dataFrameStyle(df).map((v) => v === null ? "background-color: #ffeeee;" : ""); +console.log(dataFrameStyle(df).map((v) => v === null ? "background-color: #ffeeee;" : ""));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -382,7 +384,7 @@

.setProperties(props, subset?)

+console.log(dataFrameStyle(df).setProperties({ "font-weight": "bold", color: "navy" }, ["important"]));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -437,7 +439,7 @@

.highlightNull(color?, subset?)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -501,7 +503,7 @@

.textGradient(options?)

+console.log(dataFrameStyle(df).textGradient({ cmap: "RdYlGn" }));
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -540,7 +542,7 @@

.setCaption(text)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -578,7 +580,7 @@

.setTableAttributes(attrs)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -594,10 +596,10 @@

.hide(axis?, subset?)

- +
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -618,7 +620,8 @@

.toHtml(uuid?) / .render(uuid?)

.toHtml(); // .render() is an alias // Inject into a page -document.getElementById("output").innerHTML = html; +document.getElementById("output").innerHTML = html; +console.log(html);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -636,7 +639,8 @@

.toLatex(environment?, hrules?)

+ .toLatex("tabular", true); // environment, hrules +console.log(latex);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -655,7 +659,8 @@

.exportStyles()

+// [{ row: 0, col: 1, css: "background-color: yellow;" }, ...] +console.log(records);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -672,7 +677,7 @@

.clearStyles()

+console.log(styler.clearStyles());
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/swaplevel.html b/playground/swaplevel.html index 54fdad58..c4363906 100644 --- a/playground/swaplevel.html +++ b/playground/swaplevel.html @@ -198,7 +198,8 @@

swapLevelSeries — swap two levels

const swapped = swapLevelSeries(s, 0, 1); // index tuples: [(1,"a"), (2,"a"), (1,"b")] -// values: [10, 20, 30] +// values: [10, 20, 30] +console.log(swapped);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -249,7 +250,8 @@

swapLevelDataFrame — swap row-index levels

); const swapped = swapLevelDataFrame(df, "letter", "number"); -// row index tuples: [(1,"a"), (2,"b")] +// row index tuples: [(1,"a"), (2,"b")] +console.log(swapped);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -297,7 +299,8 @@

reorderLevelsSeries — arbitrary level reordering

const s = new Series({ data: [10, 20], index: mi as unknown as Index<Label> }); const reordered = reorderLevelsSeries(s, [2, 0, 1]); -// index tuples: [("x","a",1), ("y","b",2)] +// index tuples: [("x","a",1), ("y","b",2)] +console.log(reordered);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -348,7 +351,8 @@

reorderLevelsDataFrame

); const reordered = reorderLevelsDataFrame(df, [1, 0]); -// row index tuples: [(1,"a"), (2,"b")] +// row index tuples: [(1,"a"), (2,"b")] +console.log(reordered);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/testing.html b/playground/testing.html index 49e13fcb..b6a80b37 100644 --- a/playground/testing.html +++ b/playground/testing.html @@ -186,7 +186,7 @@

Passing example

const a = new Series({ data: [1, 2, 3], name: "x" }); const b = new Series({ data: [1, 2, 3], name: "x" }); -assertSeriesEqual(a, b); +console.log(assertSeriesEqual(a, b)); // ✅ no exception thrown
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -204,7 +204,7 @@

Failing example

Click ▶ Run to execute
@@ -224,9 +224,9 @@

Float tolerance

+console.log(assertSeriesEqual(p, q, { checkExact: true })); // ❌ exact comparison fails
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -246,7 +246,7 @@

Passing example

const a = DataFrame.fromColumns({ x: [1, 2], y: [3, 4] }); const b = DataFrame.fromColumns({ x: [1, 2], y: [3, 4] }); -assertFrameEqual(a, b); // ✅ +console.log(assertFrameEqual(a, b)); // ✅
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -263,7 +263,7 @@

Ignore column order

+console.log(assertFrameEqual(a, c, { checkLike: true })); // ✅ order ignored
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -284,10 +284,10 @@

assertIndexEqual(left, right, options?)

const a = new Index(["a", "b", "c"]); const b = new Index(["a", "b", "c"]); -assertIndexEqual(a, b); // ✅ +console.log(assertIndexEqual(a, b)); // ✅ const c = new Index(["a", "b", "z"]); -assertIndexEqual(a, c); +console.log(assertIndexEqual(a, c)); // ❌ AssertionError: Index: Index values differ at position 2. left=c, right=z
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/to_datetime.html b/playground/to_datetime.html index 59e15651..99c08a60 100644 --- a/playground/to_datetime.html +++ b/playground/to_datetime.html @@ -164,20 +164,20 @@

Quick examples

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/to_from_dict.html b/playground/to_from_dict.html index 890a77e8..c84f9e95 100644 --- a/playground/to_from_dict.html +++ b/playground/to_from_dict.html @@ -170,27 +170,27 @@

Example — all orientations

); // "dict" / "columns" -toDictOriented(df, "dict"); +console.log(toDictOriented(df, "dict")); // { name: { r0: "Alice", r1: "Bob" }, score: { r0: 92, r1: 85 } } // "list" -toDictOriented(df, "list"); +console.log(toDictOriented(df, "list")); // { name: ["Alice", "Bob"], score: [92, 85] } // "records" -toDictOriented(df, "records"); +console.log(toDictOriented(df, "records")); // [ { name: "Alice", score: 92 }, { name: "Bob", score: 85 } ] // "split" -toDictOriented(df, "split"); +console.log(toDictOriented(df, "split")); // { index: ["r0", "r1"], columns: ["name", "score"], data: [["Alice", 92], ["Bob", 85]] } // "index" -toDictOriented(df, "index"); +console.log(toDictOriented(df, "index")); // { r0: { name: "Alice", score: 92 }, r1: { name: "Bob", score: 85 } } // fromDictOriented — columns (default) -fromDictOriented({ name: ["Alice", "Bob"], score: [92, 85] }); +console.log(fromDictOriented({ name: ["Alice", "Bob"], score: [92, 85] })); // fromDictOriented — index fromDictOriented( diff --git a/playground/to_numeric.html b/playground/to_numeric.html index 56911d79..cb89d3b3 100644 --- a/playground/to_numeric.html +++ b/playground/to_numeric.html @@ -205,7 +205,8 @@

3 · Series conversion

index: ["a", "b", "c"] }); toNumericSeries(prices, { errors: "coerce" }) -// Series [10.5, NaN, 22] name="price" +// Series [10.5, NaN, 22] name="price" +console.log(prices);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -246,7 +247,8 @@

5 · Live sandbox

+return JSON.stringify(result.values); +console.log(result);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/to_timedelta.html b/playground/to_timedelta.html index 584edfc5..2287c8eb 100644 --- a/playground/to_timedelta.html +++ b/playground/to_timedelta.html @@ -164,34 +164,34 @@

Quick examples

+console.log(dataFrameTransform(df, "cumsum")); +console.log(dataFrameTransform(df, { a: "sum", b: "cummin" })); // per-column +console.log(dataFrameTransform(df, "cumsum", { axis: 1 })); // row-wise
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -220,20 +220,20 @@

Examples

const s = new Series({ data: [1, 2, 3, 4] }); // cumulative sum -seriesTransform(s, "cumsum").values; // [1, 3, 6, 10] +console.log(seriesTransform(s, "cumsum").values); // [1, 3, 6, 10] // broadcast aggregate -seriesTransform(s, "sum").values; // [10, 10, 10, 10] +console.log(seriesTransform(s, "sum").values); // [10, 10, 10, 10] // multiple functions const df = seriesTransform(s, ["sum", "cumsum", "mean"]); -df.col("sum").values; // [10, 10, 10, 10] -df.col("cumsum").values; // [1, 3, 6, 10] -df.col("mean").values; // [2.5, 2.5, 2.5, 2.5] +console.log(df.col("sum").values); // [10, 10, 10, 10] +console.log(df.col("cumsum").values); // [1, 3, 6, 10] +console.log(df.col("mean").values); // [2.5, 2.5, 2.5, 2.5] // DataFrame transform const frame = DataFrame.fromColumns({ a: [1,2,3], b: [10,20,30] }); -dataFrameTransform(frame, "cumsum").col("b").values; // [10, 30, 60] +console.log(dataFrameTransform(frame, "cumsum").col("b").values); // [10, 30, 60]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/truncate.html b/playground/truncate.html index 2287cdd8..ca3530d8 100644 --- a/playground/truncate.html +++ b/playground/truncate.html @@ -203,9 +203,9 @@

truncateSeries — keep rows within [before, after]

const s = new Series({ data: [10, 20, 30, 40, 50], index: [0, 1, 2, 3, 4] }); -truncateSeries(s, 1, 3).values; // [20, 30, 40] -truncateSeries(s, 2).values; // [30, 40, 50] -truncateSeries(s, undefined, 2).values; // [10, 20, 30] +console.log(truncateSeries(s, 1, 3).values); // [20, 30, 40] +console.log(truncateSeries(s, 2).values); // [30, 40, 50] +console.log(truncateSeries(s, undefined, 2).values); // [10, 20, 30]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -258,8 +258,8 @@

truncateDataFrame — truncate rows

); const result = truncateDataFrame(df, 1, 3); -result.col("a").values; // [20, 30, 40] -result.index.values; // [1, 2, 3] +console.log(result.col("a").values); // [20, 30, 40] +console.log(result.index.values); // [1, 2, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -305,7 +305,7 @@

truncateDataFrame — truncate columns (axis=1)

const df = DataFrame.fromColumns({ a: [1, 2], b: [3, 4], c: [5, 6] }); const result = truncateDataFrame(df, "a", "b", { axis: 1 }); -result.columns.values; // ["a", "b"] +console.log(result.columns.values); // ["a", "b"]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -356,7 +356,7 @@

String index truncation

index: ["apple", "banana", "cherry", "date", "elderberry"], }); -truncateSeries(s, "banana", "date").values; // [2, 3, 4] +console.log(truncateSeries(s, "banana", "date").values); // [2, 3, 4]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/update.html b/playground/update.html index 8874d754..ccfa6937 100644 --- a/playground/update.html +++ b/playground/update.html @@ -191,7 +191,7 @@

seriesUpdate — basic overwrite

const s = new Series({ data: [1, null, 3], index: [0, 1, 2] }); const other = new Series({ data: [null, 20, null], index: [0, 1, 2] }); -seriesUpdate(s, other).values; +console.log(seriesUpdate(s, other).values); // [1, 20, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -237,7 +237,7 @@

overwrite=false — only fill NA

const s = new Series({ data: [1, null, 3] }); const other = new Series({ data: [10, 20, 30] }); -seriesUpdate(s, other, { overwrite: false }).values; +console.log(seriesUpdate(s, other, { overwrite: false }).values); // [1, 20, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -287,8 +287,8 @@

dataFrameUpdate — update from another DataFrame

const df = DataFrame.fromColumns({ a: [1, null, 3], b: [10, 20, 30] }); const other = DataFrame.fromColumns({ a: [null, 99, null] }); const result = dataFrameUpdate(df, other); -result.col("a").values; // [1, 99, 3] -result.col("b").values; // [10, 20, 30] +console.log(result.col("a").values); // [1, 99, 3] +console.log(result.col("b").values); // [10, 20, 30]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -310,7 +310,7 @@

Label alignment

const s = new Series({ data: [1, 2, 3], index: [0, 1, 2] }); // other only has label 1 — other labels unchanged const other = new Series({ data: [99], index: [1] }); -seriesUpdate(s, other).values; +console.log(seriesUpdate(s, other).values); // [1, 99, 3]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/value_counts_full.html b/playground/value_counts_full.html index 3f285240..11f53c8f 100644 --- a/playground/value_counts_full.html +++ b/playground/value_counts_full.html @@ -193,7 +193,8 @@

Basic binning

const s = new Series({ data: [1, 2, 3, 4, 5] }); const vc = valueCountsBinned(s, 2); // Index: ["(0.995, 3.0]", "(3.0, 5.005]"] -// Values: [3, 2] ← sorted by count (default) +// Values: [3, 2] ← sorted by count (default) +console.log(vc);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -212,7 +213,8 @@

Interval order (sort=false)

+// Values: [3, 2] ← in interval order +console.log(vc2);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -231,7 +233,8 @@

Proportions (normalize=true)

+// Values: [0.6, 0.4] +console.log(vc3);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -250,7 +253,8 @@

Handling NaN / null

+// NaN and null values are excluded. Total = 5. +console.log(vc4);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/wide_to_long.html b/playground/wide_to_long.html index 75482237..0f894a49 100644 --- a/playground/wide_to_long.html +++ b/playground/wide_to_long.html @@ -192,7 +192,7 @@

1 · Numeric suffix (default)

A1: [1, 2], A2: [3, 4], B1: [5, 6], B2: [7, 8], }); -wideToLong(df, ["A", "B"], "id", "year"); +console.log(wideToLong(df, ["A", "B"], "id", "year")); // id year A B // x 1 1 5 // y 1 2 6 @@ -227,7 +227,8 @@

2 · Underscore separator

// 1 pre 80 // 2 pre 90 // 1 post 85 -// 2 post 95 +// 2 post 95 +console.log(df);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -250,7 +251,7 @@

3 · Multiple id columns

gdp2020: [21, 2.7, 3.8], gdp2021: [23, 3.1, 4.2], }); -wideToLong(df, "gdp", ["country","region"], "year", { sep: "" }); +console.log(wideToLong(df, "gdp", ["country","region"], "year", { sep: "" })); // country region year gdp // US East 2020 21 // UK South 2020 2.7 diff --git a/playground/window_extended.html b/playground/window_extended.html index 0b368ebd..328f97a1 100644 --- a/playground/window_extended.html +++ b/playground/window_extended.html @@ -191,7 +191,8 @@

1. rollingSem — Standard Error of the Mean

const s = new Series({ data: [2, 4, 4, 4, 5, 5, 7, 9], name: "x" }); const sem3 = rollingSem(s, 3); -// [null, null, 0.667, 0, 0.577, 0.577, 1.155, 2.082] +// [null, null, 0.667, 0, 0.577, 0.577, 1.155, 2.082] +console.log(sem3);
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -232,7 +233,7 @@

2. rollingSkew — Fisher-Pearson Skewness

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -274,7 +275,7 @@

3. rollingKurt — Excess Kurtosis

Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
@@ -298,9 +299,9 @@

4. rollingQuantile — Rolling Quantile

const s = new Series({ data: [1, 2, 3, 4, 5] }); -rollingQuantile(s, 0.5, 3); // rolling median: [null, null, 2, 3, 4] -rollingQuantile(s, 0.25, 3); // [null, null, 1.5, 2.5, 3.5] -rollingQuantile(s, 0.75, 3); // [null, null, 2.5, 3.5, 4.5] +console.log(rollingQuantile(s, 0.5, 3)); // rolling median: [null, null, 2, 3, 4] +console.log(rollingQuantile(s, 0.25, 3)); // [null, null, 1.5, 2.5, 3.5] +console.log(rollingQuantile(s, 0.75, 3)); // [null, null, 2.5, 3.5, 4.5]
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent
diff --git a/playground/xs.html b/playground/xs.html index 7272d74b..3e838963 100644 --- a/playground/xs.html +++ b/playground/xs.html @@ -172,10 +172,10 @@

Code Examples

); // Select row "y" → Series { a: 2, b: 5 } -xsDataFrame(df, "y"); +console.log(xsDataFrame(df, "y")); // Select column "b" → Series { x: 4, y: 5, z: 6 } -xsDataFrame(df, "b", { axis: 1 }); +console.log(xsDataFrame(df, "b", { axis: 1 })); // ── MultiIndex ───────────────────────────────────────────────────────────── const mi = MultiIndex.fromTuples([ @@ -185,11 +185,11 @@

Code Examples

const miDf = new DataFrame( ... , mi); // All "A" rows → DataFrame with 2 rows -xsDataFrame(miDf, "A"); +console.log(xsDataFrame(miDf, "A")); // ── Series ───────────────────────────────────────────────────────────────── const s = new Series({ data: [10, 20, 30], index: ["a", "b", "c"] }); -xsSeries(s, "b"); // → 20 +console.log(xsSeries(s, "b")); // → 20
Click ▶ Run to execute
Ctrl+Enter to run · Tab to indent