Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在大型数据集中向CSV写入未知密钥?_Python_Csv - Fatal编程技术网

Python 如何在大型数据集中向CSV写入未知密钥?

Python 如何在大型数据集中向CSV写入未知密钥?,python,csv,Python,Csv,我目前正在编写一个脚本,该脚本将从RESTAPI查询数据,并将结果值写入CSV。数据集可能包含数十万条记录,但它以100个条目的集合返回数据。我的目标是在CSV中包含每个条目中的每个密钥 到目前为止,我所掌握的(就本问题而言,这是一个简化的结构): 问题是:每个条目不一定有相同的键。后来的一个条目丢失了一个键,这没什么大不了的。例如,我的问题是条目364引入了一个全新的密钥 我考虑过的选择: 每当我遇到一个新键时,读入输出CSV,将新键附加到标题,并将逗号附加到前一行。这将导致大量的文件I/O

我目前正在编写一个脚本,该脚本将从RESTAPI查询数据,并将结果值写入CSV。数据集可能包含数十万条记录,但它以100个条目的集合返回数据。我的目标是在CSV中包含每个条目中的每个密钥

到目前为止,我所掌握的(就本问题而言,这是一个简化的结构):

问题是:每个条目不一定有相同的键。后来的一个条目丢失了一个键,这没什么大不了的。例如,我的问题是条目364引入了一个全新的密钥

我考虑过的选择:

  • 每当我遇到一个新键时,读入输出CSV,将新键附加到标题,并将逗号附加到前一行。这将导致大量的文件I/O,我希望避免这种情况
  • 将原始JSON写入文件,而不是写入CSV。同时,在迭代数据时,建立一个所有已知键的列表。查询完API后,迭代我编写的JSON文件,并使用我构建的列表编写CSV。这将导致对数据进行2次总迭代,并且感觉不必要的复杂
  • 预先对潜在密钥列表进行硬编码。这种方法是不可能的,原因有很多

这些解决方案对我来说都不是特别优雅,这就引出了我的问题。有没有更好的方法来解决这个问题?我是否忽略了一些显而易见的事情?

选项1和选项2似乎都很合理

在创建CSV时,CSV是否需要有效且可读?如果没有,您可以在完成对API的读取后一次性追加缺少的列(这就像两种方法的组合)。如果您这样做,您可能必须在第一遍中使用常规的
csv.writer
,而不是
csv.DictWriter
,因为您的列定义在编写时会增加

需要记住的一件事是,如果整个文件预计很大(例如无法放入内存),那么您的解决方案可能需要使用流式方法,这对于CSV来说很容易,但是对于JSON来说很难。您可能还需要研究中间数据(如XML、BSON等)的JSON替代格式。

要完成所需操作,至少需要对数据进行两次传递。第一个用于确定所有可能的密钥,另一个用于将它们和相关数据写入csv文件。您可以通过选择一个高效的数据结构在两次传递之间存储数据来对此进行优化(假设您不能将数据全部存储在内存中,内存本身可能足够快,因此您不需要对其进行优化)。请参阅关于使用
tempfile.NamedTemporaryFile()
,这可能有助于编写执行此操作的代码。
import csv
resp = client.get_list()

while resp.token:
    my_data = resp.data
    process_data(my_data)
    resp = client.get_list(resp.token)

def process_data(my_data):
    #This section should write my_data to a CSV file
    #I know I can use csv.dictwriter as part of the solution
    #Notice that in this example, "fieldnames" is undefined
    #Defining it is part of the question
    with open('output.csv', 'a') as output_file:
        writer = csv.DictWriter(output_file, fieldnames = fieldnames)
        for element in my_data:
            writer.writerow(element)