使用python进行文本分析-程序在8次运行后暂停

使用python进行文本分析-程序在8次运行后暂停,python,nltk,Python,Nltk,我想对多个文本文件(>50000个文件)进行文本分析,其中一些是html脚本。我的程序(如下)迭代这些文件,依次打开每个文件,使用NLTK模块分析内容,并将输出写入CSV文件,然后使用第二个文件继续分析 该程序对单个文件运行良好,但循环在第8次运行后几乎停止,即使要分析的第9个文件不大于第8个文件。前八次迭代总共耗时10分钟,而第九次迭代耗时45分钟。第十次花了甚至超过45分钟(文件比第一次小得多) 我确信这个程序可以进一步优化,因为我对Python还是比较陌生的,但我不明白为什么在第8次运行后

我想对多个文本文件(>50000个文件)进行文本分析,其中一些是html脚本。我的程序(如下)迭代这些文件,依次打开每个文件,使用NLTK模块分析内容,并将输出写入CSV文件,然后使用第二个文件继续分析

该程序对单个文件运行良好,但循环在第8次运行后几乎停止,即使要分析的第9个文件不大于第8个文件。前八次迭代总共耗时10分钟,而第九次迭代耗时45分钟。第十次花了甚至超过45分钟(文件比第一次小得多)

我确信这个程序可以进一步优化,因为我对Python还是比较陌生的,但我不明白为什么在第8次运行后它会变得如此缓慢?任何帮助都将不胜感激。谢谢

#import necessary modules
import urllib, csv, re, nltk
from string import punctuation
from bs4 import BeautifulSoup
import glob

#Define bags of words (There are more variable, ie word counts, that are calculated)
adaptability=['adaptability', 'flexibility']

csvfile=open("test.csv", "w", newline='', encoding='cp850', errors='replace')
writer=csv.writer(csvfile)
for filename in glob.glob('*.txt'):

    ###Open files and arrange them so that they are ready for pre-processing
    review=open(filename, encoding='utf-8', errors='ignore').read()
    soup=BeautifulSoup(review)
    text=soup.get_text()

    from nltk.stem import WordNetLemmatizer
    wnl=WordNetLemmatizer()

    adaptability_counts=[]
    adaptability_counter=0
    review_processed=text.lower().replace('\r',' ').replace('\t',' ').replace('\n',' ').replace('. ', ' ').replace(';',' ').replace(', ',' ')
    words=review_processed.split(' ')
    word_l1=[word for word in words if word not in stopset]
    word_l=[x for x in word_l1 if x != ""]
    word_count=len(word_l)
    for word in words:
       wnl.lemmatize(word)
       if word in adaptability:
         adaptability_counter=adaptability_counter+1
    adaptability_counts.append(adaptability_counter)

    #I then repeat the analysis with 2 subsections of the text files
    #(eg. calculate adaptability_counts for Part I only)

    output=zip(adaptability_counts)
    writer=csv.writer(open('test_10.csv','a',newline='', encoding='cp850', errors='replace'))
    writer.writerows(output)
    csvfile.flush()

一旦打开文件,就永远不会关闭它们。我的猜测是,您的内存不足,而且需要很长时间,因为您的计算机必须交换页面文件(磁盘上)中的数据。与其只调用
open()
,还不如在完成文件时
close()
该文件,或者使用带有open结构的
,该结构将在完成后自动关闭该文件。有关更多信息,请参阅本页:

如果是我,我会改变这一行:

review=open(filename, encoding='utf-8', errors='ignore').read()
为此:

with open(filename, encoding='utf-8', errors='ignore') as f:
    review = f.read()
    ...

并确保适当缩进。打开文件时执行的代码需要缩进到
with
块中。

由于接受的答案并没有完全解决您的问题,下面是一个后续问题:

  • 您有一个列表,可以在其中查找输入中的每个单词永远不要在列表中查找单词将列表替换为集合,您将看到巨大的改进。(如果您使用列表计算单个单词,请将其替换为
    collections.counter
    ,或nltk的
    FreqDist
    )如果您的
    列表随着您读取的每个文件而增长(是吗?是否应该?),这肯定足以导致您的问题

  • 但罪魁祸首可能不止一个。您遗漏了很多代码,因此无法知道其他数据结构随着您看到的每个文件而增长,或者是否是有意的。很明显,您的代码是“二次型”的,并且随着数据的增大而变慢,这不是因为内存大小,而是因为您需要更多的步骤


  • 不必麻烦切换到数组和计数向量器,您只需将问题推迟一点即可。了解如何在固定时间内处理每个文件。如果您的算法不需要从多个文件中收集单词,最快的解决方案是在每个文件上分别运行它(这并不难实现自动化)。

    显式关闭使用
    打开的文件有什么缺点吗。它在您退出块后关闭,这可能是在您使用完它后关闭的。您的意思是从带有
    中显式调用
    close()
    ?是的,从块本身内部。类似于将open('tieline.txt',wb')作为f:f.write(response.data)f.close()的
    ,我正在使用它,我的意思是,它是冗余的。。。我不知道有什么具体的失败<代码>关闭()!你的回答很有帮助。我认为在重新初始化循环之前将结果写入csv文件会清除变量的内存,但我可能错了;我会检查一下。我不确定你在说什么,但是写出一个变量不会影响它的内容。将其他内容分配给同一变量(例如,空列表)。