This plugin provides stable hashing functionality across different polars versions.
📖 Documentation — every expression, its input and output types, and its arguments.
Examples
Cryptographic Hashers
import polars as pl
import polars_hash as plh
df = pl.DataFrame({
"foo":["hello_world"]
})
result = df.select(plh.col('foo').chash.sha256())
print(result)
┌──────────────────────────────────────────────────────────────────┐
│ foo │
│ --- │
│ str │
╞══════════════════════════════════════════════════════════════════╡
│ 35072c1ae546350e0bfa7ab11d49dc6f129e72ccd57ec7eb671225bbd197c8f1 │
└──────────────────────────────────────────────────────────────────┘
Non-cryptographic Hashers
df = pl.DataFrame({
"foo":["hello_world"]
})
result = df.select(plh.col('foo').nchash.wyhash())
print(result)
┌──────────────────────┐
│ foo │
│ --- │
│ u64 │
╞══════════════════════╡
│ 16737367591072095403 │
└──────────────────────┘
result = df.select(plh.col('foo').nchash.farmhash64())
print(result)
┌──────────────────────┐
│ foo │
│ --- │
│ u64 │
╞══════════════════════╡
│ 15605398435621216523 │
└──────────────────────┘
result = df.select(plh.col('foo').nchash.farmhash32())
print(result)
┌────────────┐
│ foo │
│ --- │
│ u32 │
╞════════════╡
│ 1719156559 │
└────────────┘
result = df.select(plh.col('foo').nchash.cityhash128())
print(result)
┌─────────────────────────────────────────┐
│ foo │
│ --- │
│ u128 │
╞═════════════════════════════════════════╡
│ 133423608296839006301901834072762183026 │
└─────────────────────────────────────────┘
result = df.select(plh.col('foo').nchash.gxhash64())
print(result)
┌─────────────────────┐
│ foo │
│ --- │
│ u64 │
╞═════════════════════╡
│ 2180020304351407825 │
└─────────────────────┘
cityhash32() and cityhash64() return the values printed above for farmhash32()
and farmhash64(). That is expected: FarmHash reuses CityHash for short input, and
hello_world is 11 bytes. See
the CityHash reference.
The GxHash expressions need a CPU with AES instructions and have no software fallback.
Every x86, x86-64 and aarch64 wheel is built for them; there are no linux-armv7 or
linux-ppc64le wheels from 0.8.0 on, because GxHash cannot be built for either. See
the GxHash reference.
Geo Hashers
df = pl.DataFrame(
{"coord": [{"longitude": -120.6623, "latitude": 35.3003}]},
schema={
"coord": pl.Struct(
[pl.Field("longitude", pl.Float64), pl.Field("latitude", pl.Float64)]
),
},
)
df.with_columns(
plh.col('coord').geohash.from_coords().alias('geohash')
)
shape: (1, 2)
┌─────────────────────┬──────────────┐
│ coord ┆ geohash │
│ --- ┆ --- │
│ struct[2] ┆ str │
╞═════════════════════╪══════════════╡
│ {-120.6623,35.3003} ┆ 9q60y60rhsgg │
└─────────────────────┴──────────────┘
pl.select(pl.lit('9q60y60rhs').geohash.to_coords().alias('coordinates'))
shape: (1, 1)
┌───────────────────────┐
│ coordinates │
│ --- │
│ struct[2] │
╞═══════════════════════╡
│ {-120.6623,35.300298} │
└───────────────────────┘
H3 Spatial Index
df = pl.DataFrame(
{"coord": [{"longitude": -120.6623, "latitude": 35.3003}]},
schema={
"coord": pl.Struct(
[pl.Field("longitude", pl.Float64), pl.Field("latitude", pl.Float64)]
),
},
)
df.with_columns(
plh.col('coord').h3.from_coords().alias('h3')
)
shape: (1, 2)
┌─────────────────────┬─────────────────┐
│ coord ┆ h3 │
│ --- ┆ --- │
│ struct[2] ┆ str │
╞═════════════════════╪═════════════════╡
│ {-120.6623,35.3003} ┆ 8c29adc423821ff │
└─────────────────────┴─────────────────┘
Time Hasher
Bins timestamps into variable-precision sliding windows of time, so rows that fall in the same window share a hash. Timestamps must lie between 1970-01-01 and 2098-01-01. A higher precision means a shorter window: 10 covers about 4 seconds, 8 about 4 minutes.
Precision may be 1 to 32, but past about 18 the hash stops changing for present-day timestamps and the extra characters are padding. The exact point depends on the date: timestamps close to 1970 keep splitting to about 21, far-future ones run out sooner.
from datetime import datetime
df = pl.DataFrame({"datetime": [datetime(2017, 2, 21, 20, 15, 13)]})
df.with_columns(
plh.col('datetime').timehash.from_datetime().alias('timehash')
)
shape: (1, 2)
┌─────────────────────┬────────────┐
│ datetime ┆ timehash │
│ --- ┆ --- │
│ datetime[μs] ┆ str │
╞═════════════════════╪════════════╡
│ 2017-02-21 20:15:13 ┆ afcccc0e1b │
└─────────────────────┴────────────┘
pl.select(pl.lit('afcccc0e1b').timehash.to_datetime().alias('datetime'))
shape: (1, 1)
┌────────────────────────────────┐
│ datetime │
│ --- │
│ datetime[μs, UTC] │
╞════════════════════════════════╡
│ 2017-02-21 20:15:11.292315 UTC │
└────────────────────────────────┘
pl.select(pl.lit('afcccc0e1b').timehash.neighbors().alias('neighbors'))
shape: (1, 1)
┌─────────────────────────────┐
│ neighbors │
│ --- │
│ struct[2] │
╞═════════════════════════════╡
│ {"afcccc0e1a","afcccc0e1c"} │
└─────────────────────────────┘
Create hash from multiple columns
df = pl.DataFrame({"foo": ["hello_world"], "bar": ["today"]})
result = df.select(plh.concat_str("foo", "bar").chash.sha256())
Hash a whole row
hash_rows gives each row bytes that no other row can make, for all column types.
Any hasher then reads those bytes.
df = pl.DataFrame(
{"foo": ["hello_world"], "bar": [42], "baz": [[1, 2, 3]], "qux": [{"a": 1}]}
)
df.select(plh.hash_rows(pl.all()).chash.sha2_256())
shape: (1, 1)
┌──────────────────────────────────────────────────────────────────┐
│ foo │
│ --- │
│ str │
╞══════════════════════════════════════════════════════════════════╡
│ 9055866af8d3c113e0a8fdb729ce8e6fa67ed5f6f51efa8235a588e88ea972f4 │
└──────────────────────────────────────────────────────────────────┘
The encoder reads the meaning of a value, not the polars storage of it. An Int32 and
the Int64 next to it make the same hash. A Datetime in milliseconds and the same
time in nanoseconds also make the same hash, and a Categorical makes the hash of its
string. The encoder does not read the column names. Therefore a new name keeps the
hash, but a new order does not. The
reference
gives all the rules and the byte layout of version 1, which does not change.
Metadata
Release files for polars-hash 0.9.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_hash-0.9.2.tar.gz | 99.0 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| polars_hash-0.9.2-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| polars_hash-0.9.2-cp310-abi3-win32.whl | CPython 3.10 | abi3 | Windows x86-32 | Details |
| polars_hash-0.9.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| polars_hash-0.9.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| polars_hash-0.9.2-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl | CPython 3.10 | abi3 | Linux glibc 2.12+ x86-32 | Details |
| polars_hash-0.9.2-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| polars_hash-0.9.2-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 49.5 MB
Release files / polars_hash-0.9.2.tar.gz
| Download URL | polars_hash-0.9.2.tar.gz |
|---|---|
| Size | 99.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e80674dc2eff4d72e3c314ea4e3da5aca613d9768f6a81a5c38b876c2042dcd5
|
|
BLAKE2b-256 checksum How to use checksums |
c429791f4a2d7014a233359a37e25b7b8f2a2f106091d8c2bb9dbdcb53bc51d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-win_amd64.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 7.5 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e3c720d633ff6b0132e8059217ea697ffe1c07e9feab6f450b1f5632eb498683
|
|
BLAKE2b-256 checksum How to use checksums |
d12a3dfb6fe79ea812858b137c9167ae6383fb129fdf7d27f9ed148da6ff1dd0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-win32.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-win32.whl |
|---|---|
| Size | 6.7 MB |
| Tags | CPython 3.10 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
2da3beac9f5cf1c338fd6a716008c0bdd3e2cc47c6f2371d0c1fa3e5f21cc6af
|
|
BLAKE2b-256 checksum How to use checksums |
e5cde087b22f423872d8fd4773060ccac177933068ee8aeb8d018efc15d22725
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 7.3 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c9225d357eb2c0a6738dbcfc2af1fb0916791b3d1f9dd9954ee5b250788d0d97
|
|
BLAKE2b-256 checksum How to use checksums |
45463e283f1a1cd17d527020ebd25241e858d4e50e9ddf06a7707a1743702b36
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 6.6 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ce11421600aa1873813d03ce667710775655321e513acae59575d310280c5f17
|
|
BLAKE2b-256 checksum How to use checksums |
f1f4e07ee12bc7e768c679b25869be6675593d7bf37b6054ad139d7d581d10cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-manylinux_2_12_i686.manylinux2010_i686.whl |
|---|---|
| Size | 7.9 MB |
| Tags | CPython 3.10 Linux glibc 2.12+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
62c1bf0ac203a9572afd047f8543f768b5a3bc099bf8ada08018561c2a896d5a
|
|
BLAKE2b-256 checksum How to use checksums |
a93b5e7dc831b04f73bb3f50842296446087dbc7e38a143189d556ba80aeb582
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 6.3 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b5001f1ae2a4a9e2013f057c67d4958d73db9d2fdf3ee7080a14b25e4ba0dc69
|
|
BLAKE2b-256 checksum How to use checksums |
9f8543004f8ea5051adb80a2d0c9c10e206b891b6fea47df07facfaa8e4503f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / polars_hash-0.9.2-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | polars_hash-0.9.2-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 7.1 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
c27a24b16e040d631f7512948d6e8eafea83b198b3c5d42c448fbe7e0a7e4011
|
|
BLAKE2b-256 checksum How to use checksums |
21083829c3dc1d0afdbafa3d353f24527e56b144fa87797176da727c380084e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|