创建一个包含来自一组 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。
- 为每个输入创建 parquet 文件
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
听起来像是合并 k 个排序数组,
找到一篇文章解决了,希望对你有帮助:
https://medium.com/outco/how-to-merge-k-sorted-arrays-c35d87aa298e
您可以使用 glob 模式读取 csv,然后调用 distinct
。
(pl.scan_csv("**/*.csv")
.distinct()
.collect())
我有 +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。
- 为每个输入创建 parquet 文件
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
听起来像是合并 k 个排序数组, 找到一篇文章解决了,希望对你有帮助: https://medium.com/outco/how-to-merge-k-sorted-arrays-c35d87aa298e
您可以使用 glob 模式读取 csv,然后调用 distinct
。
(pl.scan_csv("**/*.csv")
.distinct()
.collect())