【问题标题】:Reading csv files with glob to pass data to a database very slow使用 glob 读取 csv 文件以将数据传递到数据库非常慢
【发布时间】:2020-06-02 13:02:50
【问题描述】:

我有许多 csv 文件,我正在尝试将它们包含的所有数据传递到数据库中。出于这个原因,我发现我可以使用 glob 库来遍历我文件夹中的所有 csv 文件。以下是我使用的代码:

import requests as req
import pandas as pd
import glob
import json

endpoint = "testEndpoint"
path = "test/*.csv"

for fname in glob.glob(path):
    print(fname)

    df = pd.read_csv(fname)

    for index, row in df.iterrows():
        #print(row['ID'], row['timestamp'], row['date'], row['time'],
        #     row['vltA'], row['curA'], row['pwrA'], row['rpwrA'], row['frq'])

        print(row['timestamp'])

        testjson = {"data":
                        {"installationid": row['ID'],
                         "active": row['pwrA'],
                         "reactive": row['rpwrA'],
                         "current": row['curA'],
                         "voltage": row['vltA'],
                         "frq": row['frq'],
                         }, "timestamp": row['timestamp']}

        payload = {"payload": [testjson]}
        json_data = json.dumps(payload)
        response = req.post(
            endpoint, data=json_data, headers=headers)

此代码一开始似乎运行良好。但是,一段时间后它开始变得非常慢(我注意到这一点是因为我在上传数据时打印了时间戳)并最终完全停止。这是什么原因?我在这里做的事情真的没有效率吗?

【问题讨论】:

  • 速度逐渐下降,因为您正在迭代 (df.iterrows)。我建议您阅读所有 csv 文件,进行所有处理,然后批量加载到数据库中。我知道 postgres psycopg2(我不知道你在哪个数据库上操作)有一个允许批量加载的界面,而且速度非常快。

标签: python pandas csv glob


【解决方案1】:

我可以在这里看到 3 个可能的问题:

  1. 内存。 read_csv 速度很快,但它会将整个文件的内容加载到内存中。如果文件非常大,您可能会耗尽实际内存并开始使用性能很差的交换
  2. iterrows:您似乎构建了一个数据框 - 意思是针对按列访问优化的数据结构 - 然后按行访问它。这已经是个坏主意了,iterrows 的表现很糟糕,因为它为每行构建一个系列
  3. 每行一个帖子请求。 http 请求有其自身的开销,但此外,这意味着您一次向数据库添加行。如果这是你的数据库唯一的接口,你可能别无选择,但你应该搜索是否可以准备一堆行并作为一个整体加载。它通常提供超过一个数量级的增益。

如果没有更多信息,我很难说更多,但 IHMO 更高的增益是在数据库馈送中找到的,所以在第 3 点。如果在那一点上什么都做不了,或者如果需要进一步的性能提升,我会尝试用面向行且占用空间有限的 csv 模块替换 pandas,因为无论文件大小如何,它一次只处理一行。

最后,如果这对您的用例有意义,我会尝试使用一个线程来读取 csv 文件,该文件将提供一个队列和一个线程池以向数据库发送请求。这应该允许获得 HTTP 开销。但请注意,根据端点实现,如果真的是数据库访问限制因素,它不会有太大改善。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2021-03-13
    相关资源
    最近更新 更多