如何根据第一列的内容拆分一个巨大的 csv 文件?
- 2024-11-11 08:26:00
- admin 原创
- 21
问题描述:
我有一个 250MB 以上的大型 csv 文件需要上传
文件格式是
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
,因此输出应该是 n 个文件,其中n=group_id
输出
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 n n, x, 0.3(lets say)
我怎样才能有效地做到这一点?
解决方案 1:
awk
有能力:
awk -F "," '{print $0 >> ("FILE" $1)}' HUGE.csv
解决方案 2:
如果文件已经按 排序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) + "
")
解决方案 3:
Sed 单行命令:
sed -e '/^1,/wFile1' -e '/^2,/wFile2' -e '/^3,/wFile3' ... OriginalFile
唯一的缺点是您需要输入n 条 -e
语句(用省略号表示,这不应该出现在最终版本中)。因此,这一行代码可能会很长。
但其优点是,它只对文件进行一次遍历,无需排序,也不需要 Python。另外,它只需要一行代码!
解决方案 4:
如果行按 排序group_id
,那么itertools.groupby
这里会很有用。因为它是一个迭代器,所以您不必将整个文件加载到内存中;您仍然可以逐行写入每个文件。使用csv
加载文件(如果您还不知道的话)。
解决方案 5:
如果它们按组 ID 排序,则可以使用 csv 模块迭代文件中的行并输出。您可以在此处找到有关该模块的信息。
解决方案 6:
怎么样:
每次读取一行输入文件
split()
每一行都,
得到group_id
对于找到的每个新 group_id,打开一个输出文件
当你找到每个 groupid 时,将其添加到集合/字典中,以便可以跟踪
将该行写入适当的文件
完毕!
解决方案 7:
这里有一些值得思考的内容:
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)
解决方案 8:
以下是适用于已排序或未排序 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...
我的输出文件如下:
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 脚本运行时间约为一分钟。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件