获取CSV长度以显示进度

7
我正在处理大量的CSV文件,每个文件都包含大量行数据。我的目标是使用Python逐行读取数据并将其写入数据库。由于数据量很大,我希望能够跟踪记录已经写入了多少数据。为此,我已经计算了排队的文件数量,并在每个文件完成时加1。
我希望能够对CSV文件执行类似的操作,并显示我所在的行以及总行数(例如:当前在第1行,共X行)。我可以通过从1开始并执行类似以下代码的方式轻松获得当前行:currentRow += 1,但是我不确定如何获取总行数,而不必进行耗时的逐行读取。
此外,由于我的CSV文件都存储在zip归档文件中,因此我目前正在使用ZipFile模块来读取它们,就像这样:
#The Zip archive and the csv files share the same name
with zipArchive.open(fileName[:-4] + '.csv', 'r') as csvFile:
    lines = (line.decode('ascii') for line in csvFile)
    currentRow = 1

    for row in csv.reader(lines):
        print(row)
        currentRow += 1

有什么办法可以快速获得CSV文件的总行数吗?

可能是CSV文件中的行数的重复问题。 - Rohan Khude
1
你是想避免读取文件吗?如果不是,你可以使用 lines = len(open(csv).readlines()) - double_j
@double_j没错,我试图避免循环遍历每一行来确定总行数。然而,由于我正在读取存储在zip归档文件中的CSV文件,你的解决方案可能不适用。我已经更新了我的代码以解释我的过程。 - ng150716
2
这实际上是唯一(合理)的方法,你可以通过使用csv reader读取它来获取csv文件中行数的计数。 - Wayne Werner
我认为你应该查看Python中廉价获取行数的方法,这里有很多相关的好答案。 - Sahil M
3个回答

6

在不打开文件并计算行数的情况下,无法统计文件中的行数。

如果您的文件太大,使用row_count = sum(1 for row in file_handle)来计算行数就不太实际,并且将整个文件读入内存也是行不通的,那么就需要采用不同的方法。

很容易通过How to check file size in python?获得文件的字节数长度。当你阅读每一行时计算它的字节长度,就可以报告“目前在 4972397 字节的第 13927 个字节(2.8%)”。

对于存储在zip文件中的文件,Zipfile.getinfo(name).file_size是未压缩文件的大小。


2
从技术上讲,对于CSV文件,如果在引号字符串内部存在换行符,则可能会产生错误。 - Wayne Werner
@WayneWerner 可能会有影响,但是没有办法在不读取文件的情况下获取CSV文件中行数。这是尝试实现最佳替代方案。错误可能不是关键问题。 - James K
这可能并不是很有优势。我很想看看小文件和大文件的timeit差异是什么 - 有了这个比较,这个答案会更有用。 - Wayne Werner

5
如果您只想展示一些进度,可以尝试使用 "tqdm"。 点击此处 了解更多信息。
from tqdm import tqdm

with zipArchive.open(fileName[:-4] + '.csv', 'r') as csvFile:
    lines = [line.decode('ascii') for line in csvFile]
    currentRow = 1

    for row in tqdm(csv.reader(lines), total=len(lines)):
        print(row)
        currentRow += 1

这将为您提供一个流畅的进度条,几乎不需要您付出任何努力。

哇,这真的很简单。但是当我尝试按照你上面提到的方式使用它(for row in tqdm(csv.reader(lines)))时,它没有显示进度条,而是一系列不断增加的数字:像这样:3589382it [00:20, 171812.07it/s]。我认为这是因为它正在使用变量lines,它是一个生成器,我怀疑它无法执行len(lines)之类的操作,有什么解决方法吗? - ng150716
@ng150716 看起来 tqdm 除非知道总长度,否则不会给你提供进度条。因此,我们需要将行存储为列表并获取其长度。可能有更优化的方法来完成这个任务,但是如果您想要知道生成器的总长度,您必须完全运行它。 - Lily Mara
好的,所以我决定重新编写我的程序,而不是直接从zip存档中读取csv文件。我首先将其提取出来,然后再读取它,这使我能够从读取器创建一个列表,从而创建一个计数。 - ng150716
更优化的方式是首先逐行遍历整个CSV文件(您仍然可以显示tqdm,但没有总数,只是为了显示预处理进度),然后使用该总数再次遍历CSV文件,将每行插入到数据库中,并使用正确的总数显示tqdm进度条(从而显示真正的进度条)。 - gaborous

3

以下方法适用于我:

  • 安装tqdm: pip install tqdm
  • 读取csv文件并显示进度的代码:
    with open('./data.csv') as csv_file:
        lines = len(csv_file.readlines())

    with open('./data.csv') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        header = next(csv_reader)

        for row in tqdm(csv_reader, total=lines):
            print(row)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接