如何在 Polars 或 Pyarrow 中获取字符串列的哈希值

How to get hash of string column in Polars or Pyarrow

我有一个 Pandas DataFrame/Polars dataframe / Pyarrow table 带有字符串键列。您可以假设字符串是随机的。我想根据这个键列将该数据帧分成 N 个较小的数据帧。

对于整数列,我可以只使用 df1 = df[df.key % N == 1]df2 = df[df.key % N == 2]

我对如何使用字符串列执行此操作的最佳猜测是应用哈希函数(例如,对字符串的 ascii 值求和)将其转换为整数列,然后使用模数。

请告诉我在 Pandas、Polars 或 Pyarrow 中最有效的方法是什么,最好是在 API 中使用纯柱状操作。对于我的用例,执行 df.apply 可能太慢了。

我会尝试使用 hash_rows 来查看它在您的数据集和计算平台上的表现。 (请注意,在计算中,我实际上只选择了 key 字段和 运行 上的 hash_rows

N = 50
df = df.with_column(
    pl.lit(df.select(['key']).hash_rows() % N).alias('hash')
)

我只是 运行 在一个 32 核系统上有近 4900 万条记录的数据集上,它在几秒钟内完成。 (我数据集中的 'key' 字段是人的姓氏。)

我还应该注意,有一个 partition_by 方法可能对分区有帮助。

我对@cbilots 的回答有一点补充。 Polars 有一个 hash 表达式,因此计算分区 ID 很简单。

如果将其与 partition_by 结合使用,您可以通过以下方式以极快的速度创建分区:

df = pl.DataFrame({
    "strings": ["A", "A", "B", "A"],
    "payload": [1, 2, 3, 4]
})


N = 2
(df.with_columns([
     (pl.col("strings").hash() % N).alias("partition_id")
]).partition_by("partition_id"))
[shape: (3, 3)
 ┌─────────┬─────────┬──────────────┐
 │ strings ┆ payload ┆ partition_id │
 │ ---     ┆ ---     ┆ ---          │
 │ str     ┆ i64     ┆ u64          │
 ╞═════════╪═════════╪══════════════╡
 │ A       ┆ 1       ┆ 0            │
 ├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ A       ┆ 2       ┆ 0            │
 ├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
 │ A       ┆ 4       ┆ 0            │
 └─────────┴─────────┴──────────────┘,
 shape: (1, 3)
 ┌─────────┬─────────┬──────────────┐
 │ strings ┆ payload ┆ partition_id │
 │ ---     ┆ ---     ┆ ---          │
 │ str     ┆ i64     ┆ u64          │
 ╞═════════╪═════════╪══════════════╡
 │ B       ┆ 3       ┆ 1            │
 └─────────┴─────────┴──────────────┘]

分区的分组和具体化将并行完成。