python - 最大限度地减少大型 CSV 文件中 python 的搜索时间
问题描述
我有一个包含大约 700 行左右和 8 列的 CSV 文件,但是最后一列有一个非常大的文本块(每个里面有足够的多个长段落)。
我想通过 python 实现一个文本搜索功能,它可以让我返回所有文本与第 8 列数据内部匹配的行(这意味着它需要遍历整个内容)。
解决这个问题并最小化搜索时间的最快方法可能是什么?
解决方案
您可以将 csv 文件转储到sqlite数据库中,并使用 sqlite 的全文搜索功能为您进行搜索。
此示例代码显示了它是如何完成的。有几点需要注意:
- 它假定 csv 文件有一个标题行。如果不是这种情况,您需要提供列名(或者只使用通用名称,如“col1”、“col2”等)。
- 它搜索csv 中的所有列;如果不希望这样做,请在创建 SQL 语句之前过滤掉其他列(和标题值)。
- 如果您希望能够将结果与 csv 文件中的行进行匹配,则需要创建一个包含行号的列。
import csv
import sqlite3
import sys
def create_table(conn, cols, name='mytable'):
stmt = f"""CREATE VIRTUAL TABLE "{name}" USING fts5({cols})"""
with conn:
conn.execute(stmt)
return
def populate_table(conn, reader, cols, ncols, name='mytable'):
placeholders = ', '.join(['?'] * ncols)
stmt = f"""INSERT INTO "{name}" ({cols})
VALUES ({placeholders})
"""
# Filter out any blank rows in the csv
reader = filter(None, reader)
with conn:
conn.executemany(stmt, reader)
return
def search(conn, term, cols, name='mytable'):
stmt = f"""SELECT {cols}
FROM "{name}"
WHERE "{name}" MATCH ?
"""
with conn:
cursor = conn.cursor()
cursor.execute(stmt, (term,))
result = cursor.fetchall()
return result
def main(path, term):
result = 'NO RESULT SET'
try:
conn = sqlite3.connect(':memory:')
with open(path, 'r') as f:
reader = csv.reader(f)
# Assume headers are in the first row
headers = next(reader)
ncols = len(headers)
cols = ', '.join([f'"{x.strip()}"' for x in headers])
create_table(conn, cols)
populate_table(conn, reader, cols, ncols)
result = search(conn, term, cols)
finally:
conn.close()
return result
if __name__ == '__main__':
print(main(*sys.argv[1:]))
推荐阅读
- android - 段落级别跨越
- excel - 使用 ActiveWorkbook.SaveCopyAs 文件名时出现运行时错误
- python - 使用 python 抓取 AJIAX 页面:如何复制 POST 请求
- java - 查看 AllData 表列的上次更新时间
- angular - 在Angular 6中从一个组件导航到另一个组件时,主题不起作用
- php - Office365 独立 php 应用授权
- symfony - Symfony Webpack Encore:从 Bundle 导入 .js
- node.js - 运行“npm run”时无法解析“react”
- c# - 在 Docker 中运行项目时获取“System.TypeInitializationException”
- c++ - 带有 enable_if 的模板专业化在 Clang 中失败,适用于 GCC