如何存储非常大(csv)文件的行索引?

时间:2019-06-12 14:40:52

标签: csv indexing

我正在处理大型csv文件(>> 10 ^ 6行),并且需要一些操作的行索引。我需要在识别删除的文件的两个版本之间进行比较,因此我认为最容易包含行索引。我猜想,行数会很快使传统整数效率低下。我反对让列包含以纯文本形式表示634567775577作为行索引的想法(紧随其后的是实际数据行)。对于这种情况是否有最佳实践建议? 生成的文件必须保持纯文本格式,因此不能选择序列化/ sqlite。

目前,我正在考虑基于实际行数据的索引(例如,将行数据连接,转换为base64等),但是这比普通整数更合理吗?每个文件中都不应有重复的行,所以我想这可能是一种方法。

干杯,萨莎

Ps:我对最初的问题进行了重大修改以供澄清

3 个答案:

答案 0 :(得分:0)

您可以使用常规数字。

Python不惧怕大量数字:)(嗯,达到您描述的数量级...)

只需打开python shell,然后键入10**999,看看它没有溢出或任何异常。

答案 1 :(得分:0)

在Python中,整数没有实际的位限制。在Python 2中,从技术上讲,int是32位,而long是32位以上。但是,如果您只是声明数字,则该类型转换将隐式进行。 Python 3只有一种类型,它只关心内存空间。 因此,如果您真的想添加索引,则没有理由不使用整数。

答案 2 :(得分:0)

Python内置库包含SQLite,这是一个自包含的,适合所有文件的DBMS-与通常的看法相反,该性能非常好。如果要由不具有并发性的单个应用程序查询记录,则与专用DBMS相比,它需要一个单独的守护程序。

因此,从本质上讲,您可以将CSV转储到SQLITE数据库中并创建所需的索引-甚至可以在所有四列上创建索引。

这是您可以自定义创建此类数据库的模板脚本- 我猜一次插入次数是“ 1000”数字,但是可以 并非最佳选择-尝试调整插入速度太慢。

import sqlite3
import csv

inserts_at_time = 1000

def create_and_populate_db(dbfilename, csvfilename):
    db = sqlite3.connect(dbfilename)
    db.execute("""CREATE TABLE data (col1, col2, col3, col4)""")
    for col_name in "col1 col2 col3 col4".split():
        db.execute(f"""CREATE INDEX {col_name} ON data ({col_name})""")

    with open(csvfilanem) as in_file:
        reader = csv.reader(in_file)
        next(reader)  # skips header row
        total = counter = 0
        lines = []
        while True:
            for counter, line in zip(range(inserts_at_time), reader):
                lines.append(line)
            db.executemany('INSERT INTO data VALUES (?,?,?,?)', lines)
            total += counter
            counter = 0
            lines.clear()
            print("\b" * 80, f"Inserted {counter} lines - total {total}")
            if counter < inserts_at_time - 1:
                break