0

我有 +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)

  • 运行duckdb并执行:
CREATE TABLE my_table AS SELECT DISTINCT * FROM 'my_directory/*.parquet'

学分来自 DuckDB 的 Mark Mytherin

4

2 回答 2

1

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

(pl.scan_csv("**/*.csv")
 .distinct()
 .collect())
于 2022-01-07T17:30:14.150 回答
1

听起来像是合并 k 排序数组,我找到了解决方案的文章,希望它可以帮助: https ://medium.com/outco/how-to-merge-k-sorted-arrays-c35d87aa298e

于 2021-11-17T14:21:37.203 回答