[英]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 或其他一些脚本语言中,有没有更快的方法来做到这一点?
附加信息:
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.