创建一个包含来自一组 CSV 的唯一值的 polars 数据框

create a polars dataframe containing unique values from a set of CSVs

我有 +3000 个包含 +10 列的 CSV。我需要的是从其中两个中获取所有唯一值。我能够读取极坐标中的唯一值:

import polars as pl

df1 = pl.read_csv("test1.biobank.tsv.gz", sep='\t', dtype={"#chrom": pl.Utf8}, n_threads=8, columns=["#chrom", "pos"], new_columns=["chr", "pos"]).drop_duplicates()

剩下的文件我可以一个一个看完,即:

df2 = pl.read_csv("test2.biobank.tsv.gz", sep='\t', dtype={"#chrom": pl.Utf8}, n_threads=8, columns=["#chrom", "pos"], new_columns=["chr", "pos"]).drop_duplicates()

检查是否所有值都不相等:

if not df1.frame_equal(df2):
    df = df1.vstack(df2)
    del(df1)
    del(df2)  

然后 .drop_duplicates()。但是由于所有输入文件都已经按两列 (chr, pos) 排序,并且在 16M 输入行中有数千个差异,我希望有更好的方法来做到这一点。

提前感谢您的帮助

丹麦

编辑

还有另一种方法可以使用 Polars 和 DuckDB。

tsv_pattern = "gwas_*.gz"

for fn in glob.glob(tsv_pattern):
    print(fn)
    parquet_fn = fn.replace(".gz", ".chr_pos.parquet")
    df = pl.read_csv(fn, sep='\t', dtype={"#chrom": pl.Utf8}, n_threads=8, columns=["#chrom", "pos"], new_columns=["chr", "pos"]).drop_duplicates()
    df.to_parquet(parquet_fn, compression='zstd')
    del(df)

CREATE TABLE my_table AS SELECT DISTINCT * FROM 'my_directory/*.parquet'

致谢 DuckDB 的 Mark Mytherin

听起来像是合并 k 个排序数组, 找到一篇文章解决了,希望对你有帮助: https://medium.com/outco/how-to-merge-k-sorted-arrays-c35d87aa298e

您可以使用 glob 模式读取 csv,然后调用 distinct

(pl.scan_csv("**/*.csv")
 .distinct()
 .collect())