-1

我正在处理大型 csv 文件(>> 10^6 行),并且需要一个行索引来执行某些操作。我需要在识别删除的文件的两个版本之间进行比较,所以我认为包含行索引是最简单的。我猜想行数会很快使传统整数效率低下。我反对让一列包含纯文本中的 634567775577 作为行索引(后跟实际数据行)的想法。对于这种情况,是否有任何最佳实践建议?结果文件必须保持纯文本,因此序列化/sqlite 不是一个选项。

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

干杯,萨沙

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

4

3 回答 3

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
于 2019-06-12T15:09:31.550 回答
0

您可以使用常规数字。

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

只需打开一个 python shell 并输入10**999,看看它没有溢出或任何东西。

于 2019-06-12T14:44:59.710 回答
0

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

于 2019-06-12T14:46:20.557 回答