sqlite 最大限度地缩短大型CSV文件中文本的搜索时间

guykilcj  于 2022-12-29  发布在  SQLite
关注(0)|答案(1)|浏览(90)

我有一个CSV文件,大约有700行和8列,但是最后一列有一个非常大的文本块(每个里面有足够的多个长段落)。
我想通过python实现一个文本搜索函数,返回所有文本与第8列数据匹配的行(这意味着它需要遍历所有行)。
什么可能是最快的方法来解决这个问题,并尽量减少搜索时间?

xytpbqjk

xytpbqjk1#

您可以将csv文件转储到sqlite数据库中,然后使用sqlite的full text search功能为您执行搜索。
这个示例代码展示了如何完成它。有几件事需要注意:

  • 它假设csv文件有一个标题行,如果不是这样,你需要提供列名称(或者只是使用通用名称,如“col 1”,“col 2”等)。
  • 搜索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:]))

相关问题