【问题标题】:Parsing large csv file to tinydb takes forever将大型 csv 文件解析为 tinydb 需要很长时间
【发布时间】:2016-12-23 13:52:11
【问题描述】:

我有一个包含 15 列和大约 100 万行的大型 csv 文件。我想将数据解析成 tinyDB。我使用的代码如下:

import csv
from tinydb import TinyDB

db = TinyDB('db.monitor')
table = db.table('Current')

i=0

datafile = open('newData.csv', 'rb')
data=csv.reader(datafile, delimiter = ';')

for row in data:
    table.insert({'WT_ID': row[0], 'time': row[1], 'MeanCurrent': row[2], 'VapourPressure': row[3], 'MeanVoltage':row[4], 'Temperature': row[5], 'Humidity': row[6], 'BarPressure': row[7], 'RPM': row[8], 'WindSector': row[9], 'WindSpeed': row[10], 'AirDensity': row[12], 'VoltageDC': row[13], 'PowerSec': row[14], 'FurlingAngle': row[15]})
    i=i+1
    print i

但是,这确实需要很长时间。我设置了 i 变量来跟踪进度,虽然在第一行它运行得很快,但现在已经一个多小时了,它以几乎 1Hz 的速度解析了大约 10000 行

我找不到类似的东西,所以任何帮助将不胜感激

谢谢

【问题讨论】:

  • 这应该移到codereview.stackexchange.com - 也许你应该看看insert_multiple()
  • 我遇到了同样的问题,在 300 次插入后插入变得非常慢(比如 1/秒)。安装 ujson 并使用 insert_multiple 将我的插入速度提高了几个数量级。没有精确测量,但从 50 秒到 1 或 2...所以使用 insert_multiple 是这里的关键!

标签: python performance csv tinydb


【解决方案1】:

TinyDB 是最佳选择吗?您似乎需要一个跨国数据库,而 TinyDB 是面向文档的。最重要的是,来自文档:Wy not use TinyDB

如果您需要高级功能或高性能,TinyDB 不适合您

您的进程运行速度非常慢,因为您正在将数据累积到 RAM 中。作为一种解决方法,您可以将 csv 拆分为较小的主干并用它填充您的脚本。这样,每次迭代之间的内存都可以清理干净。

tinyDB 完全无法管理这么多信息。

【讨论】:

    【解决方案2】:

    本周我遇到了一个类似的问题,其解决方案是使用 CachingMiddleware:

    import csv
    from tinydb import TinyDB
    from tinydb.storages import JSONStorage
    from tinydb.middlewares import CachingMiddleware
    
    db = TinyDB('db.monitor', storage=CachingMiddleware(JSONStorage))
    table = db.table('Current')
    
    i=0
    
    datafile = open('newData.csv', 'rb')
    data=csv.reader(datafile, delimiter = ';')
    
    for row in data:
        table.insert({'WT_ID': row[0], 'time': row[1], 'MeanCurrent': row[2], 'VapourPressure': row[3], 'MeanVoltage':row[4], 'Temperature': row[5], 'Humidity': row[6], 'BarPressure': row[7], 'RPM': row[8], 'WindSector': row[9], 'WindSpeed': row[10], 'AirDensity': row[12], 'VoltageDC': row[13], 'PowerSec': row[14], 'FurlingAngle': row[15]})
        i=i+1
        print i
    

    【讨论】:

      【解决方案3】:

      我从未使用过 tinyDB,但您可以尝试以下 2 个选项

      1. 熊猫到 DB

      http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html

      Pandas 可以批量读取 csv 数据,比逐行读取文件更快

      1. 以块而不是逐行读取 csv 文件,然后为其创建插入语句,而不是为每一行创建插入语句。

      【讨论】:

        【解决方案4】:

        TinyDB 会很慢,因为它将所有内容都加载到 RAM 中。我不确定是否有任何好的替代方案,尽管您可能对我不久前写的这个由 SQLite 支持的文档存储库感兴趣:

        https://github.com/skorokithakis/goatfish

        您可以在某些字段上创建索引,并将所有内容都转换为 SQL 查询,因此性能相当不错。

        【讨论】:

          【解决方案5】:

          如果您从 csv 文件解析数据,手动构建文件会更快。我建议如下:

          import json
          counter = 0
          with open(csv_file) as fh, open('test.db','w') as db:
              keys = None
              db.write('{"_default": {')
              spacer = ''
              for line in fh:
                  if not keys:
                      # This is the header row
                      keys = line[:-1].replace(" ", "_").split('\t')
                  else:
                      counter += 1
                      # These are the data rows
                      values = line[:-1].split('\t')
                      db.write('{}"{}":{}'.format(spacer,counter,json.dumps(dict(zip(keys, values)))))
                      spacer = ','
                  if counter % 1000 == 0:
                      print( 'counter: {:10d}'.format(counter), end='\r')
              db.write('}}')
          
               
          

          【讨论】:

            【解决方案6】:

            用户 Pandas 写入 Json 文件会快很多。

            generated_rules.to_json('./Data/rules.json', orient='index', index='true')
            

            然后编辑生成的json文件,在json文件中添加table或者default eg

            之前

            {"0": {...}, "1":{...}
            

            之后

            {rules:{"0": {...}, "1":{...}}
            

            然后将这个 json 文件读取为小数据库。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多