如何在python中读取一个大的tsv文件并将其转换为csv
Posted
技术标签:
【中文标题】如何在python中读取一个大的tsv文件并将其转换为csv【英文标题】:How to read a large tsv file in python and convert it to csv 【发布时间】:2019-08-01 07:44:00 【问题描述】:我有一个较大的 tsv
文件(大约 12 GB),我想将其转换为 csv
文件。对于较小的tsv
文件,我使用以下代码,它可以工作但速度很慢:
import pandas as pd
table = pd.read_table(path of tsv file, sep='\t')
table.to_csv(path andname_of csv_file, index=False)
但是,此代码不适用于我的大文件,并且内核在中间重置。
有什么办法可以解决这个问题吗?有谁知道这个任务是否可以用 Dask 而不是 Pandas 来完成?
我使用的是 Windows 10。
【问题讨论】:
您在使用基于 unix 的系统吗? 如果是,您可以使用以下命令:tr '\t' ',' <input.tsv >output.csv
,
可以由另一个字段分隔符更改
我在 Windows 10 上工作。你的第二条评论我不清楚
如果我们已经回答了您的问题,您能否接受以下详细信息:***.com/help/someone-answers
【参考方案1】:
您可以逐行读取并逐行处理,而不是一次将所有行加载到内存中:
Python 3.x:
fs=","
table = str.maketrans('\t', fs)
fName = 'hrdata.tsv'
f = open(fName,'r')
try:
line = f.readline()
while line:
print(line.translate(table), end = "")
line = f.readline()
except IOError:
print("Could not read file: " + fName)
finally:
f.close()
输入(hrdata.tsv):
Name Hire Date Salary Sick Days remaining
Graham Chapman 03/15/14 50000.00 10
John Cleese 06/01/15 65000.00 8
Eric Idle 05/12/14 45000.00 10
Terry Jones 11/01/13 70000.00 3
Terry Gilliam 08/12/14 48000.00 7
Michael Palin 05/23/13 66000.00 8
输出:
Name,Hire Date,Salary,Sick Days remaining
Graham Chapman,03/15/14,50000.00,10
John Cleese,06/01/15,65000.00,8
Eric Idle,05/12/14,45000.00,10
Terry Jones,11/01/13,70000.00,3
Terry Gilliam,08/12/14,48000.00,7
Michael Palin,05/23/13,66000.00,8
命令:
python tsv_csv_convertor.py > new_csv_file.csv
注意:
如果您使用 Unix
环境,只需运行以下命令:
tr '\t' ',' <input.tsv >output.csv
【讨论】:
【参考方案2】:如果我错了,请纠正我,但 TSV 文件基本上是 CSV 文件,使用制表符而不是逗号。为了在 python 中有效地翻译它,您需要遍历源文件的行,用逗号替换制表符,并将新行写入新文件。您不需要使用任何模块来执行此操作,用 Python 编写解决方案实际上非常简单:
def tsv_to_csv(filename):
ext_index = filename.rfind('.tsv')
if ext_index == -1:
new_filename = filename + '.csv'
else:
new_filename = filename[:ext_index] + '.csv'
with open(filename) as original, open(new_filename, 'w') as new:
for line in original:
new.write(line.replace('\t', ','))
return new_filename
像这样遍历行只会将每一行一一加载到内存中,而不是将整个内容加载到内存中。不过,处理 12GB 的数据可能需要一段时间。
更新: 事实上,现在我想起来了,在这么大的文件上使用二进制 I/O 可能会快得多,然后在文件的大块上一次用逗号替换制表符。此代码遵循该策略:
from io import FileIO
# This chunk size loads 1MB at a time for conversion.
CHUNK_SIZE = 1 << 20
def tsv_to_csv_BIG(filename):
ext_index = filename.rfind('.tsv')
if ext_index == -1:
new_filename = filename + '.csv'
else:
new_filename = filename[:ext_index] + '.csv'
original = FileIO(filename, 'r')
new = FileIO(new_filename, 'w')
table = bytes.maketrans(b'\t', b',')
while True:
chunk = original.read(CHUNK_SIZE)
if len(chunk) == 0:
break
new.write(chunk.translate(table))
original.close()
new.close()
return new_filename
在我使用 1GB TSV 文件的笔记本电脑上,第一个函数需要 4 秒才能转换为 CSV,而第二个函数需要 1 秒。如果您的存储能够跟上,调整 CHUNK_SIZE 参数可能会加快速度,但 1MB 对我来说似乎是最佳选择。
使用另一个答案中提到的tr
对我来说需要 3 秒,因此分块 python 方法似乎最快。
【讨论】:
【参考方案3】:您可以使用Python内置的read
和write
逐行重写文件。这可能需要一些时间来处理,具体取决于您的文件大小,但它不应该耗尽内存,因为您正在逐行工作。
with open("input.tsv", "r") as input_file:
for line in input_file:
with open("output.csv", "a") as output:
line = line.replace("\t", ",")
output.write(line)
【讨论】:
这个答案应该可以工作,但它不必要地打开和关闭输入中每一行的输出文件,如果输入为 12GB 大,这可能会发生很多。这可能会减慢很多。最好在 for 循环之外打开输出文件,并使用模式 'w' 而不是 'a'。通过这些更改,您的答案基本上与我的相同。 我同意。我写我的代码试图尽可能地可读,因为 OP 似乎没有任何直接通过 Python 操作文本文件的知识。如果他觉得有必要,他可以稍后考虑优化代码,或者他可以让它运行一段时间,因为他现在只需要这个特定文件。【参考方案4】:您可以使用chunksize
分段遍历整个文件。注意这里使用.read_csv()
而不是.read_table()
df = pd.DataFrame()
for chunk in pd.read_csv('Check1_900.csv', header=None, names=['id', 'text', 'code'], chunksize=1000):
df = pd.concat([df, chunk], ignore_index=True)
source
您也可以试试low_memory=False
标志 (source)。
接下来是memory_map
(向下滚动到https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)
memory_map : bool,默认为 False
如果为 filepath_or_buffer 提供了文件路径,则将文件对象直接映射到内存并直接从那里访问数据。使用此选项可以提高性能,因为不再有任何 I/O 开销。
请注意,to_csv()
具有类似的功能。
【讨论】:
以上是关于如何在python中读取一个大的tsv文件并将其转换为csv的主要内容,如果未能解决你的问题,请参考以下文章