【问题标题】:How do I build a CSV with data returned from multiple API calls in Python?如何使用 Python 中多个 API 调用返回的数据构建 CSV?
【发布时间】:2013-08-29 20:46:50
【问题描述】:

我想构建一个 CSV 文件,结合来自多个 API 调用的数据。我对基本的 Python 没问题,我可以调用 API,提取 JSON 数据,并将数据写入 CSV。我需要帮助的地方是有效地合并数据,以便在数据提取完成后将其写入 CSV。

这是直接来自 API 请求的数据:

{u'dateTime': u'2011-03-28', u'value': u'2298'},
{u'dateTime': u'2011-03-29', u'value': u'2322'},
{u'dateTime': u'2011-03-30', u'value': u'2309'},
{u'dateTime': u'2011-03-31', u'value': u'2224'},
{u'dateTime': u'2011-04-01', u'value': u'2763'},
{u'dateTime': u'2011-04-02', u'value': u'3543'},

所以我会考虑将很多内容合并在一起:

>APICALL1
2011-03-28,2298
2011-03-29,2322
2011-03-30,2309

>APICALL2
2011-03-28,432
2011-03-29,0
2011-03-30,444

每个 API 调用结果看起来都差不多:日期和值。日期的格式总是相同的,所以这是我们共同的元素。

对于给定的日期和值,可能没有值或返回 0,所以我需要能够考虑没有数据的情况。

理想的输出应该是这样的:

2011-03-28,2298,432,23952,765,31
2011-03-29,2322,0,432353,766,31
2011-03-30,2309,444,2343923,0,32
2011-03-31,2224,489,3495,765,33

我有大约 15 次调用,每个返回响应包含大约 800 行数据(基本上是 800 天,未来每天增长 1 行)。我需要每天运行几次,所以随着它的增长,我在某种程度上担心效率。不幸的是,历史数据可能会发生变化,所以我每次运行命令时都需要重建整个列表。但是,历史数据很少更改,并且只有很小的百分比变化,所以如果仅更新数据有效率,我愿意接受。

我知道我可以做的一个选项是从第一个 API 调用将所有内容写入 CSV 文件,然后重新打开文件并为每个后续调用将更多数据写入 CSV(即 15 次单独的读取和写入每个程序执行到 CSV)。这对我来说听起来不是很有效。

我应该在内存中使用 SQLite 来构建数据集,然后最后将其转储到 CSV 吗?列表更好吗?我不擅长 SQL,虽然我知道如果这是正确的方法会很危险。

【问题讨论】:

    标签: python api csv data-structures


    【解决方案1】:

    您可以为此使用pandas 库。

    import sys
    import pandas as pd
    
    # Simulation of return values from the calls
    calls = [
        [
            {u'dateTime': u'2011-03-28', u'value': u'2298'},
            {u'dateTime': u'2011-03-29', u'value': u'2322'},
            {u'dateTime': u'2011-03-30', u'value': u'2309'},
        ],
        [
            {u'dateTime': u'2011-03-28', u'value': u'28'},
            {u'dateTime': u'2011-03-29', u'value': u'22'},
            {u'dateTime': u'2011-03-30', u'value': u'09'},
        ]
    ]
    
    # Create an initial empty data frame
    df = pd.DataFrame()
    # Make the consecutive calls
    for i, call in enumerate(calls):
        # Create the new DataFrame from the data you got
        df_new = pd.DataFrame(call).set_index('dateTime')
        # Rebane the column to avoid collision
        df_new.rename(columns={'value': 'value_%s' % i}, inplace=True)
        # Merge it with the current data frame
        df = pd.concat([df, df_new], axis=1)
    # Save data to file (I'm using here the sys.stdout, just
    # to print it to console.
    df.to_csv(sys.stdout, header=None)
    

    结果:

    2011-03-28,2298,28
    2011-03-29,2322,22
    2011-03-30,2309,09
    

    【讨论】:

    • 谢谢维克多!我运行了您的确切代码,我得到:“引发异常('项目名称重叠')”。我相信原因是两个 JSON 响应都使用“值”作为索引名称。如果我在第二个调用响应中将索引名称更改为“value2”,那么您的代码就可以工作。有没有办法在 pandas 中处理这个问题,或者我应该在使用 pd 之前处理数据?
    • @user2726872 您可以通过重命名列来处理它。我更新了代码。您可能使用的是真正旧版本的 pandas,因为新版本可以处理重复名称。
    • 我现在收到一个错误,即“就地”是关键字。我的问题一定是老熊猫。我从 Ubuntu 的存储库中安装了“python-pandas”,它一定很旧。我将致力于更新 pandas 而不是修复过时的代码。感谢您的帮助!
    • @user2726872 肯定是的。最新的 ubuntu 附带 0.10.1 版本的 pandas,最新版本是 0.12。最简单的更新方法是从源代码构建或安装 Anaconda 或 Canopy。
    • 我只是使用了 'sudo pip install pandas --update' 而不是依赖 Ubuntu 12.04 LTS 存储库中包含的 pandas。它现在正在工作。再次感谢您的帮助和及时回复。
    【解决方案2】:

    这听起来像是数据库(如 SQLite)的工作。创建一个表,其中第一列作为日期,每个 API 有一列。允许在 API 列中使用 NULL。

    然后,对于每个 API,读取数据并仅更新/插入(更新插入)指定日期的那一列。这可以完全独立于 CSV 生成。

    一旦数据在数据库中,生成 CSV 应该是微不足道的。

    使用日期列上的索引更新历史数据会容易得多。

    【讨论】:

      猜你喜欢
      • 2019-10-14
      • 2021-01-24
      • 2015-12-14
      • 1970-01-01
      • 2022-01-26
      • 2014-01-28
      • 2016-10-16
      • 2019-11-23
      • 2021-02-20
      相关资源
      最近更新 更多