Python 如何使用';iterable';对象

Python 如何使用';iterable';对象,python,iterator,gensim,doc2vec,Python,Iterator,Gensim,Doc2vec,由于我在中提出的问题,我的代码内存不足。然后,我编写了第二个代码,使其具有一个iterablealldocs,而不是一个all-in-memoryalldocs。我根据对的解释更改了代码。我不熟悉流的概念,我无法解决我得到的错误 此代码读取给定路径的所有文件夹的所有文件。每个文件的上下文由两行中的文档名及其上下文组成。例如: clueweb09-en0010-07-00000 dove gif剪贴画鸽子剪贴画图片hiox free birds india网页图标剪贴画添加偶然发现 clueweb

由于我在中提出的问题,我的代码内存不足。然后,我编写了第二个代码,使其具有一个iterable
alldocs
,而不是一个all-in-memory
alldocs
。我根据对的解释更改了代码。我不熟悉流的概念,我无法解决我得到的错误

此代码读取给定路径的所有文件夹的所有文件。每个文件的上下文由两行中的文档名及其上下文组成。例如:

clueweb09-en0010-07-00000

dove gif剪贴画鸽子剪贴画图片hiox free birds india网页图标剪贴画添加偶然发现

clueweb09-en0010-07-00001

谷歌书签雅虎书签php脚本java脚本jsp脚本授权脚本html教程css教程

第一个代码:

# coding: utf-8
 import string
 import nltk
 import nltk.tokenize 
 from nltk.corpus import stopwords
 import re
 import os, sys 

 import MySQLRepository

 from gensim import utils
 from gensim.models.doc2vec import Doc2Vec
 import gensim.models.doc2vec
 from gensim.models.doc2vec import LabeledSentence
 from boto.emr.emrobject import KeyValue


 def readAllFiles(path):
    dirs = os.listdir( path )
    for file in dirs:
        if os.path.isfile(path+"/"+file):
           prepareDoc2VecSetting(path+'/'+file)
       else:
           pf=path+"/"+file
           readAllFiles(pf)      

def prepareDoc2VecSetting (fname):
    mapDocName_Id=[]
    keyValues=set()
   with open(fname) as alldata:
        a= alldata.readlines()
        end=len(a)
        label=0
        tokens=[]
        for i in range(0,end):
            if a[i].startswith('clueweb09-en00'):
               mapDocName_Id.insert(label,a[i])
               label=label+1
               alldocs.append(LabeledSentence(tokens[:],[label]))
               keyValues |= set(tokens)
               tokens=[]
           else:
               tokens=tokens+a[i].split()  

   mydb.insertkeyValueData(keyValues) 

   mydb.insertDocId(mapDocName_Id)


   mydb=MySQLRepository.MySQLRepository()

  alldocs = [] 
  pth='/home/flr/Desktop/newInput/tokens'
  readAllFiles(ipth)

  model = Doc2Vec(alldocs, size = 300, window = 5, min_count = 2, workers = 4)
  model.save(pth+'/my_model.doc2vec')

第二代码:(我没有考虑与DB相关的部分)

这就是错误:

回溯(最近一次调用上次):文件 “/home/flashkar/git/doc2vec_have/doc2vec_have/KNN/testiterator.py”, 第44行,在 model=Doc2Vec(所有文档,大小=300,窗口=5,最小计数=2,>workers=4)文件 “/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py”, 第618行,在init self.build\u vocab(documents,trim\u rule=trim\u rule)文件>“/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/word2vec.py”, 第523行,内建 self.scan_vocab(句子,progress_per=progress_per,>trim_rule=trim_rule)#初始调查文件 “/home/flashkar/anaconda/lib/python2.7/site->packages/gensim/models/doc2vec.py”, 第655行,在scan_vocab中 对于文档号,枚举(文档)中的文档:文件>“/home/flashkar/git/doc2vec\u haven/doc2vec\u haven/KNN/testiterator.py”, 国际热核实验堆第40行 yield-labeledEntence(标记[:],tpl)索引器:列表索引超出范围


您使用生成器函数是因为您不想存储所有文档,但仍将所有文档存储在
alldocs
中。您只需
生成LabeledEntence(令牌[:],tpl[1]])


当前发生的情况是,您正在向列表追加内容并返回该列表。这就是为什么您会得到AttributeError。此外,在每次迭代中,您都会添加到列表中,这意味着在每次迭代中,我,您都会返回我和我之前的所有文档

我更新了代码,但出现了新的错误。另外,你能解释一下你答案的第二部分吗?我无法理解。我认为你应该首先尝试调试你的代码,当你真的遇到一个特定的问题时,就开始这样做。为了给你指明正确的方向,你应该在prepareAllDocs中将iter_文档与iter合并,使事情变得更简单。您还应该检查Python中的enumerate,这样您就不需要使用readlines()读取所有数据,也不必在iter_文档中增加标签。我尝试调试,但我可以找到问题。你的意思是我逐行阅读而不是读行()为什么?我不能使用enumerate,因为每个文件的标签与以下代码中的索引不同
对于索引,enumerate(fname)中的行:
对,我错过了,但你仍然可以使用它,这样你就不必继续索引a。你的“第二个代码”在正确的轨道上,但是:(1)您仍在将每一行
追加到
mapDocName\u Id
——因此将所有内容都放入内存列表中;(2)
tokens
在您测试它的地方不可能是非空的,因为它在每次循环迭代之前都被设置为
[]
,所以您永远不会产生任何结果;(3) 您现在将一个元组传递到LabeledEntence,而不是它所期望的两个列表;(4) 您不需要自己循环
alldocs
,当它正常工作时,您只需将
alldocs
传递到Doc2Vec一次。
import gensim
import os


from gensim.models.doc2vec import Doc2Vec
import gensim.models.doc2vec
from gensim.models.doc2vec import LabeledSentence



class prepareAllDocs(object):

    def __init__(self, top_dir):
        self.top_dir = top_dir

    def __iter__(self):
    mapDocName_Id=[]
    label=1
    for root, dirs, files in os.walk(top_directory):
        for fname in files:
            print fname
            inputs=[]
            tokens=[]
            with open(os.path.join(root, fname)) as f:
                for i, line in enumerate(f):          
                    if line.startswith('clueweb09-en00'):
                        mapDocName_Id.append(line)
                        if tokens:
                            yield LabeledSentence(tokens[:],[label])
                            label+=1
                            tokens=[]
                    else:
                        tokens=tokens+line.split()
                yield LabeledSentence(tokens[:],[label])

pth='/home/flashkar/Desktop/newInput/tokens/'
allDocs = prepareAllDocs('/home/flashkar/Desktop/newInput/tokens/')
for doc in allDocs:
    model = Doc2Vec(allDocs, size = 300, window = 5, min_count = 2, workers = 4)
model.save(pth+'/my_model.doc2vec')