From a0a5df20b419f2bb8397c0c4887f3793395854f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 23:46:42 +0000 Subject: [PATCH 1/4] =?UTF-8?q?Iteration=20296:=20+hashPandasObject=20?= =?UTF-8?q?=E2=80=94=20FNV-1a=2064-bit=20hashing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run: https://github.com/githubnext/tsessebe/actions/runs/25139337654 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- playground/hash_pandas_object.html | 98 ++++++++++++ playground/index.html | 5 + src/index.ts | 2 + src/stats/hash_pandas_object.ts | 209 +++++++++++++++++++++++++ src/stats/index.ts | 2 + tests/stats/hash_pandas_object.test.ts | 209 +++++++++++++++++++++++++ 6 files changed, 525 insertions(+) create mode 100644 playground/hash_pandas_object.html create mode 100644 src/stats/hash_pandas_object.ts create mode 100644 tests/stats/hash_pandas_object.test.ts diff --git a/playground/hash_pandas_object.html b/playground/hash_pandas_object.html new file mode 100644 index 00000000..972d0fc1 --- /dev/null +++ b/playground/hash_pandas_object.html @@ -0,0 +1,98 @@ + + +
+ + +hashPandasObject
+ Compute FNV-1a 64-bit hash values for each element of a
+ Series or each row of a DataFrame.
+ Mirrors pandas.util.hash_pandas_object.
+
import { Series, hashPandasObject } from "tsb";
+
+const s = new Series({ data: ["apple", "banana", "apple"], index: [0, 1, 2] });
+const h = hashPandasObject(s, { index: false });
+
+// Same value β same hash
+console.log(h.iat(0) === h.iat(2)); // true (both "apple")
+console.log(h.iat(0) === h.iat(1)); // false ("apple" β "banana")
+
+
+ import { DataFrame, hashPandasObject } from "tsb";
+
+const df = new DataFrame({
+ id: [1, 2, 3],
+ name: ["Alice", "Bob", "Alice"],
+ age: [30, 25, 30],
+});
+
+const rowHashes = hashPandasObject(df, { index: false });
+// Rows 0 and 2 are identical β same hash
+console.log(rowHashes.iat(0) === rowHashes.iat(2)); // true
+console.log(rowHashes.iat(0) === rowHashes.iat(1)); // false
+
+
+ import { DataFrame, hashPandasObject } from "tsb";
+
+const df = new DataFrame({
+ a: [1, 2, 1, 3],
+ b: ["x", "y", "x", "z"],
+});
+
+const hashes = hashPandasObject(df, { index: false });
+const seen = new Set<number>();
+const uniqueRows: number[] = [];
+
+for (let i = 0; i < df.shape[0]; i++) {
+ const h = hashes.iat(i);
+ if (!seen.has(h)) {
+ seen.add(h);
+ uniqueRows.push(i);
+ }
+}
+// uniqueRows = [0, 1, 3] β row 2 is a duplicate of row 0
+console.log(uniqueRows);
+
+
+ import { Series, hashPandasObject } from "tsb";
+
+const s = new Series({ data: [42, 42], index: ["a", "b"] });
+
+// index=true (default): different index β different hash
+const withIdx = hashPandasObject(s, { index: true });
+console.log(withIdx.iat(0) === withIdx.iat(1)); // false
+
+// index=false: only values matter
+const noIdx = hashPandasObject(s, { index: false });
+console.log(noIdx.iat(0) === noIdx.iat(1)); // true
+
+
+ float64 numbers (the 64-bit bit-pattern cast via Number(BigInt)).
+ dataFrameStyle(df) Β· highlightMax / highlightMin / highlightNull / highlightBetween Β· backgroundGradient / textGradient Β· barChart Β· format / formatIndex Β· apply / applymap / map Β· setCaption / setTableStyles / hide Β· toHtml / toLatex. Mirrors pandas.DataFrame.style (Styler).
hashPandasObject(s) Β· hashPandasObject(df) Β· index option. Mirrors pandas.util.hash_pandas_object. FNV-1a 64-bit per element or row.
+hashPandasObject
+ hashPandasObject(obj) computes FNV-1a 64-bit hash values for each element
+ of a Series or each row of a DataFrame β mirroring
+ pandas.util.hash_pandas_object.
+ Edit any code block below and press βΆ Run
+ (or Ctrl+Enter) to execute it live in your browser.
+
- Compute FNV-1a 64-bit hash values for each element of a
- Series or each row of a DataFrame.
- Mirrors pandas.util.hash_pandas_object.
+ Hash each element of a Series. Identical values produce identical hashes;
+ pass { index: false } to ignore the index label when computing the hash.
import { Series, hashPandasObject } from "tsb";
+
+
+ TypeScript
+
+
+
+
+
+ import { Series, hashPandasObject } from "tsb";
const s = new Series({ data: ["apple", "banana", "apple"], index: [0, 1, 2] });
const h = hashPandasObject(s, { index: false });
// Same value β same hash
-console.log(h.iat(0) === h.iat(2)); // true (both "apple")
-console.log(h.iat(0) === h.iat(1)); // false ("apple" β "banana")
-
+console.log("apple===apple:", h.iat(0) === h.iat(2)); // true
+console.log("apple===banana:", h.iat(0) === h.iat(1)); // false
+console.log("hashes:", [...h.values]);
+ Click βΆ Run to execute
+ Ctrl+Enter to run
+
+ import { DataFrame, hashPandasObject } from "tsb";
+
+
+ 2 Β· DataFrame row hashing
+
+ Hash each row of a DataFrame. Rows with identical values across all columns
+ produce the same hash, making this useful for deduplication and change detection.
+
+
+
+ TypeScript
+
+
+
+
+
+ import { DataFrame, hashPandasObject } from "tsb";
const df = new DataFrame({
id: [1, 2, 3],
@@ -46,12 +252,29 @@ DataFrame row hashing
const rowHashes = hashPandasObject(df, { index: false });
// Rows 0 and 2 are identical β same hash
-console.log(rowHashes.iat(0) === rowHashes.iat(2)); // true
-console.log(rowHashes.iat(0) === rowHashes.iat(1)); // false
-
+console.log("row0===row2:", rowHashes.iat(0) === rowHashes.iat(2)); // true
+console.log("row0===row1:", rowHashes.iat(0) === rowHashes.iat(1)); // false
+ Click βΆ Run to execute
+ Ctrl+Enter to run
+
+
- Deduplication with hashes
- import { DataFrame, hashPandasObject } from "tsb";
+
+
+ 3 Β· Deduplication with hashes
+
+ Use row hashes to find unique rows efficiently β a common pattern when
+ duplicated() is too slow on large DataFrames.
+
+
+
+ TypeScript
+
+
+
+
+
+ import { DataFrame, hashPandasObject } from "tsb";
const df = new DataFrame({
a: [1, 2, 1, 3],
@@ -59,10 +282,10 @@ Deduplication with hashes
});
const hashes = hashPandasObject(df, { index: false });
-const seen = new Set<number>();
+const seen = new Set();
const uniqueRows: number[] = [];
-for (let i = 0; i < df.shape[0]; i++) {
+for (let i = 0; i < df.shape[0]; i++) {
const h = hashes.iat(i);
if (!seen.has(h)) {
seen.add(h);
@@ -70,29 +293,77 @@ Deduplication with hashes
}
}
// uniqueRows = [0, 1, 3] β row 2 is a duplicate of row 0
-console.log(uniqueRows);
-
+console.log("unique row indices:", uniqueRows);
+ Click βΆ Run to execute
+ Ctrl+Enter to run
+
+
- Controlling index inclusion
- import { Series, hashPandasObject } from "tsb";
+
+
+ 4 Β· Controlling index inclusion
+
+ By default (index: true), the index label is mixed into the hash.
+ Set index: false to hash only the values.
+
+
+
+ TypeScript
+
+
+
+
+
+ import { Series, hashPandasObject } from "tsb";
const s = new Series({ data: [42, 42], index: ["a", "b"] });
// index=true (default): different index β different hash
const withIdx = hashPandasObject(s, { index: true });
-console.log(withIdx.iat(0) === withIdx.iat(1)); // false
+console.log("index=true, iat(0)===iat(1):", withIdx.iat(0) === withIdx.iat(1)); // false
// index=false: only values matter
const noIdx = hashPandasObject(s, { index: false });
-console.log(noIdx.iat(0) === noIdx.iat(1)); // true
-
+console.log("index=false, iat(0)===iat(1):", noIdx.iat(0) === noIdx.iat(1)); // true
+ Click βΆ Run to execute
+ Ctrl+Enter to run
+
+
+
+
+
+ π§ͺ Scratch Pad
+ Write your own hashPandasObject code below. All exports from tsb are available.
+
+
+ TypeScript β Scratch Pad
+
+
+
+
+
+ import { Series, DataFrame, hashPandasObject } from "tsb";
+
+// Try it! Hash a Series of numbers.
+const nums = new Series({ data: [10, 20, 10, 30] });
+const hashes = hashPandasObject(nums, { index: false });
-
- Algorithm: FNV-1a 64-bit (FowlerβNollβVo), a fast non-cryptographic hash
- chosen for its excellent avalanche properties on short inputs. Results are stored as
- float64 numbers (the 64-bit bit-pattern cast via Number(BigInt)).
+console.log("10===10:", hashes.iat(0) === hashes.iat(2));
+console.log("10===20:", hashes.iat(0) === hashes.iat(1));
+console.log("all hashes:", [...hashes.values]);
+ Click βΆ Run to execute
+ Ctrl+Enter to run
+
+
+
-
-
+
+
+