我有一個Excel 2010文件(xlsx)的列表,需要搜索一個特定的值。由於xslx是二進制格式,因此無法使用普通文本編輯器完成。所以我做的每個文件蟒蛇多處理工作者內存消耗無限增加
- 獲取文件名
- 在大熊貓開放
- 轉換數據框以下,以numpy的陣列
- 的價值
這需要多處理,因爲它校驗陣列不是I/O限制的。熊貓的東西和數組轉換需要時間。所以我建立了一個我的腳本的多處理版本(見下面):
問題是每個工作進程的內存消耗。雖然每個xlsx文件只有100kb,但每個工作人員可以創建2GB的連續峯值。我不明白爲什麼在處理新文件之前未釋放內存。這種方式在處理文件列表之前耗盡內存。
這個問題似乎不是隊列,而是熊貓的東西。
這是我的代碼。它可以用你係統上的任何xlsx文件進行測試。
import pandas as pd
import multiprocessing as mp
import glob
path = r'c:\temp'
fileFilter = 'serial.xlsx'
searchString = '804.486'
def searchFile(tasks, results, searchString):
"""Iterates over files in tasks and searches in file for the
occurence of 'searchString'.
Args:
-----
tasks: queue of strings
Files to look in
results: queue of strings
Files where the searchString was found
searchString: str
the string to be searched
"""
# for files in the queue
for task in iter(tasks.get, 'STOP'):
# read the filestructre into memory
xfile = pd.ExcelFile(task)
# iterate all sheets
for sheet in xfile.sheet_names[:3]:
# read the sheet
data = pd.read_excel(xfile, sheet)
# check if searchString is in numpy representation of dataframe
if searchString in data.values.astype(str):
# put filename in results queue
results.put(task)
break
xfile.close()
if __name__ == "__main__":
# get all files matching the filter that are in the root path
print('gathering files')
files = glob.glob(path + '\**\{}'.format(fileFilter), recursive=True)
# setup of queues and variables
n_proc = 2
tasks = mp.Queue()
results = mp.Queue()
print('Start processing')
# setup processes and start them
procs = [mp.Process(target=searchFile,
args=(tasks, results, searchString))
for x in range(n_proc)]
for p in procs:
p.daemon = True
p.start()
# populate queue
for file in files:
tasks.put(file)
for proc in procs:
tasks.put('STOP')
for p in procs:
p.join()
# print results
for result in range(results.qsize()):
print(results.get())
print('Done')
作爲備註 - 「.xlsx」文件是zip壓縮的歸檔文件,其中帶有xml。如果您唯一需要的是搜索一個值,您可以解壓並在沒有任何額外模塊的情況下搜索流。 –
這不是唯一要做的事情....我可以使用python內部zip模塊解壓縮它們嗎? – RaJa
試圖解壓縮xlsx文件,並且它會生成許多xml文檔:對於樣式,對於每個工作表,主題......用這些值查找xml文檔相當困難。 – RaJa