【问题标题】:Read CSV file with limit and offset读取带有限制和偏移量的 CSV 文件
【发布时间】:2020-05-26 12:33:32
【问题描述】:

我正在使用以下代码将 CSV 文件读入字典。

file_name = path+'/'+file.filename
with open(file_name, newline='') as csv_file:
    csv_dict = [{k: v for k, v in row.items()}
                for row in csv.DictReader(csv_file)]
    for item in csv_dict:
        call_api(item)

现在这是读取文件并为每一行调用函数。随着行数的增加,调用次数也会增加。此外,由于数据量很大,因此无法将所有内容加载到内存并从那里拆分和调用 API。所以我想采用一种方法,以便在 SQL 查询的情况下使用limitoffset 读取文件。但是如何在 Python 中做到这一点?我没有在 csv 文档中看到任何指定行数和跳过行的选项。是否有人可以提出更好的方法也可以。

【问题讨论】:

  • 您的缩进错误。你的文件是什么样的?只是一个文件吗?每行有多少“列”?里面有几行? DYZ“修复”了你的缩进——这对你来说是这样的吗?
  • 你迭代整个解析的字典,为什么首先通过列表理解来解析所有行?只是逐行调用你的api也逐行调用?
  • 你能举个例子吗?
  • 我有一个文件。对于测试,它有五条记录和三列。我正在使用 csv.DictReader 将其读入字典。这有助于我获得附加到每个项目的列标题。然后我调用 API。
  • 如果您的问题得到解决,请将答案标记为已接受,以便其他人可以看到您的问题已得到解答

标签: python csv


【解决方案1】:

你可以在内存中直接调用你的 api:

with open(file_name, newline='') as csv_file:
    for row in csv.DictReader(csv_file): 
        call_api(row)        # call api with row-dictionary, don't persist all to memory 

您可以在 for 循环之前使用 next(row) 跳过行:

with open(file_name, newline='') as csv_file:
    for _ in range(10):   # skip first 10 rows
        next(csv_file)        
    for row in csv.DictReader(csv_file):

您可以在使用continue 之间跳过行:

with open(file_name, newline='') as csv_file:
    for (i,row) in enumerate(csv.DictReader(csv_file)):
        if i%2 == 0: continue                  # skip every other row

您可以简单地计算已解析的行数并在 n 行完成后中断:

n = 0
with open(file_name, newline='') as csv_file:
    for row in csv.DictReader(csv_file):
        if n == 50: 
            break
        n += 1

您可以结合这些方法跳过 100 行并取 200,只取每 2 行 - 这模仿 limitoffset 并在行号上使用模数进行破解.

或者你使用一些对 csv 来说很棒的东西,比如 pandas:

【讨论】:

    【解决方案2】:

    一种解决方案是使用 pandas 读取 csv:

    import pandas as pd
    
    file_name = 'data.csv'
    OFFSET = 10
    LIMIT = 24
    CHSIZE = 6
    header = list('ABC')
    reader = pd.read_csv(file_name, sep=',',
                         header=None, names=header,          # Header 'A', 'B', 'C'
                         usecols=[0, 1, 4],                  # Select some columns
                         skiprows=lambda idx: idx < OFFSET,  # Skip lines
                         chunksize=CHSIZE,                   # Chunk reading
                         nrows=LIMIT)
    
    for df_chunk in reader:
        # Each df_chunk is a DataFrame, so
        # an adapted api may be needed to
        # call_api(item)
        for row in df_chunk.itertuples():
            print(row._asdict())
    

    【讨论】:

    • 谢谢。这工作正常。唯一的问题是我不需要索引列。即使我尝试使用index_col=False,它也会选择索引。我们还需要同时提供limitchunksize
    • 可能是 usecolsindex_col 重叠。您不需要使用nrows。需要chunksize选项才能获得分块读取文件的效果。
    • 好的。我的意思是当我读取数据时,每行都显示Index': 1 等。我不需要这个,只需要来自 CSV 的数据。
    • 该索引是DataFrame 数据结构的一部分。更具体地说,它是RangeIndex,是DataFrame 使用的默认索引类型。有关更多详细信息,我强烈推荐pandas.pydata.org/pandas-docs/stable/getting_started
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    • 2022-12-20
    • 2014-08-26
    • 2016-06-09
    • 1970-01-01
    相关资源
    最近更新 更多