我正在处理大型csv文件(>> 10 ^ 6行),并且需要一些操作的行索引。我需要在识别删除的文件的两个版本之间进行比较,因此我认为最容易包含行索引。我猜想,行数会很快使传统整数效率低下。我反对让列包含以纯文本形式表示634567775577作为行索引的想法(紧随其后的是实际数据行)。对于这种情况是否有最佳实践建议? 生成的文件必须保持纯文本格式,因此不能选择序列化/ sqlite。
目前,我正在考虑基于实际行数据的索引(例如,将行数据连接,转换为base64等),但是这比普通整数更合理吗?每个文件中都不应有重复的行,所以我想这可能是一种方法。
干杯,萨莎
Ps:我对最初的问题进行了重大修改以供澄清
答案 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