我正在處理一個很長的串列串列(如果你把它放在一個檔案中,我說的是 10 GB),一個清理過的語料庫。在我的腳本中,我為它分配了一個名稱,然后在另一個與 word2vec/spacy 和語意相似度有關的函式中使用它(計算單詞串列中的每個單詞的語意相似度,即背景關系的相似程度這些詞出現在其中)。我的腳本中有很多步驟,我要求它在一些步驟之后列印一些東西,全部列印到輸出檔案中。我正在使用 bash 來執行腳本。已經 3 個小時了,我的輸出檔案中沒有任何內容,我認為這意味著串列尚未分配名稱。但是,當我運行一個只有串列的 .py 腳本(也分配給一個名稱)時,它需要的時間很短。此外,模型通常加載得非常快,所以這也不應該是問題。所以。..我在這里做錯了嗎?這就是我制作串列的方式(該程序有效,我已經有了串列!)而實際串列只是一個巨大的串列串列:
from tqdm import tqdm
import re
import nltk
import string
from nltk.tokenize import sent_tokenize
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
punct = string.punctuation '??' '``'
def read_lines_from_big_file(path):
with open(path, 'r', encoding='latin-1') as fp:
for line in fp:
if len(line) > 1:
parts = word_tokenize(line)
yield parts
contexts_big = []
for split_line in tqdm(read_lines_from_big_file('.../corpus.txt')):
if 'CURRENT' not in split_line:
clean_2 = [re.sub('\x93|\x94|\x92|l\'|un\'','',x.strip(punct).lower()) for x in split_line if re.sub('\x93|\x94|\x92|l\'|un\'','',x.strip(punct).lower()) not in stopwords.words('italian') #don't include if the word is a stopword
and re.sub('\x93|\x94\x92|l\'|un\'','',x.strip(punct).lower()) != " " #don't include extra empty spaces
and re.sub('\x93|\x94\x92|l\'|un\'','',x.strip(punct).lower()) not in punct #double check that all punct is removed
and len(re.sub('\x93|\x94\x92|l\'|un\'','',x.strip(punct).lower())) > 1
and not re.match(r'http\S |\d |\n|www\S ', re.sub('\x93|\x94\x92|l\'|un\'','',x.strip(punct).lower()))] #to remove any remaining stopwords or just random letters
contexts_big.append(clean_2)
else:
continue
contexts_big = [[...],[...],[...],...]
謝謝你的幫助!
uj5u.com熱心網友回復:
當您處理大檔案時,您必須考慮記憶體管理。讓我們拆開這個序列:
with open("...stimoli.txt", 'r') as stimoli:
read = stimoli.read().split("\n")
stimoli = [x.replace(" ", "") for x in read]
首先,我們有stimoli.read(). 這會將整個檔案作為單個字串讀入記憶體。在整個檔案都在記憶體中之前,該陳述句無法繼續。所以,有10GB。
接下來,我們有.split("\n"). 這將從單個 10GB 字串開始,將搜索換行符,并創建一個包含行的串列。此串列將是另一個 10GB,必須與第一個同時存在于記憶體中。那總共是 20GB 的記憶體。那是巨大的。
現在,我們將 10GB 串列分配給read,因此有一個出色的參考。接下來,我們這樣做:[x.replace(" ", "") for x in read] 由于外括號,必須在記憶體中創建另一個完整串列。該串列也將是 10GB。
因此,這組簡單的行創建了 30GB 的分配,其中 20GB 將在陳述句退出時保留。
與此相比:
with open("...stimoli.txt", 'r') as stimoli:
stimol = [x.replace(" ", "") for x in stimoli]
file.readline重復呼叫,一次不必分配多于一行。它最終會創建一個 10GB 的字串串列,但我們只需要分配 10GB,而不是 30GB。
uj5u.com熱心網友回復:
在您的原始代碼中,我可以看到您一遍又一遍地重復一組繁重的計算,而您可能可以執行一次并重用結果。下面的架構怎么樣?
for split_line in tqdm(read_lines_from_big_file('.../corpus.txt')):
if 'CURRENT' not in split_line:
tmp = [
re.sub('\x93|\x94|\x92|l\'|un\'', '', x.strip(punct).lower())
for x
in split_line
]
clean_2 = [
x
for x
in tmp
if x not in stopwords.words('italian')
and x != " "
and x not in punct
and len(x) > 1
and not re.match(r'http\S |\d |\n|www\S ', x)
]
contexts_big.append(clean_2)
else:
continue
您執行一次剝離、小寫和正則運算式替換。然后,您驗證結果。我不確定我的正則運算式是否正確,因為它們不相同,但非常相似,以至于我認為這是一個錯字。這可以進一步完善,但我懷疑這種變化會帶來明顯的加速。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/393527.html
