![](/img/trans.png)
[英]How to Split a huge csv into multiple csv's based on column header
[英]How to split a huge csv file based on content of first column?
group_id, application_id, reading
和数据可能看起来像1, a1, 0.1 1, a1, 0.2 1, a1, 0.4 1, a1, 0.3 1, a1, 0.0 1, a1, 0.9 2, b1, 0.1 2, b1, 0.2 2, b1, 0.4 2, b1, 0.3 2, b1, 0.0 2, b1, 0.9..... n, x, 0.3(lets say)
group_id
划分文件,所以 output 应该是 n 个文件,其中n=group_id
Output
File 1 1, a1, 0.1 1, a1, 0.2 1, a1, 0.4 1, a1, 0.3 1, a1, 0.0 1, a1, 0.9
和
File2 2, b1, 0.1 2, b1, 0.2 2, b1, 0.4 2, b1, 0.3 2, b1, 0.0 2, b1, 0.9.....
和
File nn, x, 0.3(lets say)
我怎样才能有效地做到这一点?
awk
有能力:
awk -F "," '{print $0 >> ("FILE" $1)}' HUGE.csv
如果文件已经按group_id
排序,您可以执行以下操作:
import csv
from itertools import groupby
for key, rows in groupby(csv.reader(open("foo.csv")),
lambda row: row[0]):
with open("%s.txt" % key, "w") as output:
for row in rows:
output.write(",".join(row) + "\n")
Sed单线:
sed -e '/^1,/wFile1' -e '/^2,/wFile2' -e '/^3,/wFile3' ... OriginalFile
唯一的缺点是你需要输入n -e
语句(由省略号表示,不应出现在最终版本中)。 所以这个单线可能是一个很长的路线。
但是,好处是它只会传递一个文件,不会进行排序,也不需要python。 此外,它是一个一个惊人的班轮!
如果行按group_id
排序,那么itertools.groupby
在这里很有用。 因为它是一个迭代器,所以你不必将整个文件加载到内存中; 你仍然可以逐行编写每个文件。 使用csv
加载文件(如果您还不知道它)。
怎么样:
split()
每行打开,
得到group_id
这里有一些食物虽然适合你:
import csv
from collections import namedtuple
csvfile = namedtuple('scvfile',('file','writer'))
class CSVFileCollections(object):
def __init__(self,prefix,postfix):
self.prefix = prefix
self.files = {}
def __getitem__(self,item):
if item not in self.files:
file = open(self.prefix+str(item)+self.postfix,'wb')
writer = csv.writer(file,delimiter = ',', quotechar = "'",quoting=csv.QUOTE_MINIMAL)
self.files[item] = csvfile(file,writer)
return self.files[item].writer
def __enter__(self): pass
def __exit__(self, exc_type, exc_value, traceback):
for csvfile in self.files.values() : csvfile.file.close()
with open('huge.csv') as readFile, CSVFileCollections('output','.csv') as output:
reader = csv.reader(readFile, delimiter=",", quotechar="'")
for row in reader:
writer = output[row[0]]
writer.writerow(row)
这是一个适用于已排序或未排序 ID 的解决方案。 未排序版本的唯一开销是多次打开目标(组 ID)CSV:
import csv
reader = csv.reader(open("test.csv", newline=""))
prev_id = None
out_file = None
writer = None
for row in reader:
this_id = row[0]
if this_id != prev_id:
if out_file is not None:
out_file.close()
fname = f"file_{this_id}.csv"
out_file = open(fname, "a", newline="")
writer = csv.writer(out_file)
prev_id = this_id
writer.writerow(row)
这是测试输入,但现在 1 和 2 交错:
1, a1, 0.1
2, b1, 0.1
1, a1, 0.2
2, b1, 0.2
1, a1, 0.4
2, b1, 0.4
1, a1, 0.3
2, b1, 0.3
1, a1, 0.0
2, b1, 0.0
1, a1, 0.9
2, b1, 0.9
当我运行它时,我看到:
./main.py
opening file_1.csv for appending...
opening file_2.csv for appending...
opening file_1.csv for appending...
opening file_2.csv for appending...
opening file_1.csv for appending...
opening file_2.csv for appending...
opening file_1.csv for appending...
opening file_2.csv for appending...
opening file_1.csv for appending...
opening file_2.csv for appending...
opening file_1.csv for appending...
opening file_2.csv for appending...
我的 output 文件如下所示:
1, a1, 0.1
1, a1, 0.2
1, a1, 0.4
1, a1, 0.3
1, a1, 0.0
1, a1, 0.9
和
2, b1, 0.1
2, b1, 0.2
2, b1, 0.4
2, b1, 0.3
2, b1, 0.0
2, b1, 0.9
我还创建了一个假的大文件,289MB,有 100 个 ID 组(每个 ID 250_000 行),我的解决方案运行了大约 12 秒。 作为比较,使用groupby()
的公认答案在大 CSV 上运行大约 10 秒; 高评级 awk 脚本运行大约一分钟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.