繁体   English   中英

基于groupby千次拆分csv文件

[英]Split csv file thousands of times based on groupby

(大卫埃里克森的问题的改编here

给定一个 CSV 文件,其中包含 A、B 和 C 列和一些值:

echo 'a,b,c' > file.csv
head -c 10000000 /dev/urandom | od -d | awk 'BEGIN{OFS = ","}{print $2, $3, $4}' | head -n 10000 >> file.csv

我们想按列 a 和 b 排序:

sort -t ',' -k1,1n -k2,2n file.csv > file_.csv
head -n 3 file_.csv
>a,b,c
3,50240,18792
7,54871,39438

然后为每个唯一对(a, b)创建一个名为'{a}_Invoice_{b}.csv'的新 CSV 。

主要挑战似乎是写入数千个文件的 I/O 开销 - 我开始尝试使用awk但遇到了awk: 17 makes too many open files

在 awk、Python 或其他一些脚本语言中,有没有更快的方法来做到这一点?

附加信息:

  • 我知道我可以在 Pandas 中做到这一点 - 我正在寻找一种使用文本处理的更快方法
  • 虽然我使用urandom生成样本数据,但真实数据具有重复值的运行:例如a=3, b=7的几行。 如果是这样,这些应该保存为一个文件。 (这个想法是复制 Pandas 的 groupby -> to_csv)

在 python 中:

import pandas as pd

df = pd.read_csv("file.csv")
for (a, b), gb in df.groupby(['a', 'b']):
    gb.to_csv(f"{a}_Invoice_{b}.csv", header=True, index=False)

在 awk 中,您可以像这样拆分,您需要将 header 放回每个结果文件中:

awk -F',' '{ out=$1"_Invoice_"$2".csv"; print >> out; close(out) }' file.csv

添加 header 线回来:

awk -F',' 'NR==1 { hdr=$0; next } { out=$1"_Invoice_"$2".csv"; if (!seen[out]++) {print hdr > out} print >> out; close(out); }' file.csv

最后一个示例的好处是输入file.csv不需要排序,只需一次处理即可。

由于您的输入将按关键字段进行排序,因此您只需要:

sort -t ',' -k1,1n -k2,2n file.csv |
awk -F ',' '
NR==1 { hdr=$0; next }
{ out = $1 "_Invoice_" $2 ".csv" }
out != prev {
    close(prev)
    print hdr > out
    prev = out
}
{ print > out }
'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM