所以我试图读取一堆非常大的数据文件,每个文件都需要相当长的时间来加载。我正试图弄清楚如何以最快的方式加载它们,而不会遇到内存问题。一旦数据文件以正确的方式加载到数组中,我不需要写入它们,只需要读取。我一直在尝试将它并行化,但没能算出来。
假设我有400个时间文件。每个文件都是tab分隔的,有30个变量,每个变量有40000个数据点。我想创建一个400x30x40000数组,以便我可以轻松访问点。将数据文件设置为前40k点用于变量1,第二个40k点用于变量2,依此类推。
我写了一个函数,正确加载时间文件并将其正确存储在我的数组中。我遇到的问题是如何并行化它。如果我把它放在for循环中并迭代I,这确实有效。
import h5py
import pandas as pd
h5file = h5py.File('data.h5','a')
data = h5file.create_dataset("default",(len(files),len(header),numPts))
# is shape 400x30x40000
def loadTimes(files,i,header,numPts,data):
# files has 400 elements
# header has 30 elements
# numPts is an integer
allData = pd.read_csv(files[i],delimiter="t",skiprows=2,header=None).T
for j in range(0,len(header)):
data[i,j,:] = allData[0][j*numPts:(j+1)*numPts]
del allData
files是subprocess.check_output
加载的时间文件列表(大约有400个元素),header是变量列表,从另一个文件加载(其中有30个元素)。numPts是每个变量的点数(大约是40k)。
我已经尝试使用pool.map
加载数据,但发现它不喜欢多个参数。我还尝试使用partial、zip和lambda函数,但它们似乎都不像我的数组。
我对这个方法并不是一成不变的。如果有更好的方法,我会非常感激。每次加载所有这些数据会花费太长时间。我的计算表明,在我的计算机上使用一个核心将需要大约3小时的加载时间。我会用掉很多我的记忆。我可以使用另一台有更多内核的机器,这实际上是我要做的,我想正确地利用它们。
所以我如何解决这个问题是使用h5文件格式。我所做的是编写循环,使它们只有iter
def LoadTimeFiles(i):
from pandas import read_csv
import h5py as h5
dataFile = h5.File('data.h5','r+')
rFile = dataFile['files'][i]
data = dataFile['data']
lheader = len(data[0,:,0])
numPts = len(data[0,0,:])
allData = read_csv(rFile,delimiter="t",skiprows=2,header=None,low_memory=False).T
for j in range(0,lheader):
data[i,j,:] = allData[0][j*numPts:(j+1)*numPts]
del allData
dataFile.close()
def LoadTimeFilesParallel(np):
from multiprocessing import Pool, freeze_support
import h5py as h5
files = h5.File('data.h5','r')
numFiles = len(files['data'][:,0,0])
files.close()
pool = Pool(np)
freeze_support
pool.map(LoadTimeFiles,range(numFiles))
if __name__ == '__main__':
np = 5
LoadTimeFilesParallel(np)
因此,既然我以h5格式存储数据,我认为我会很棘手,并在每个循环中加载它(我可以看到读取h5文件没有时间延迟)。我在read_csv
命令中添加了low_memory=False
选项,因为它使它运行得更快。j循环非常快,所以我不需要加速它。
现在每个LoadTimeFile
循环大约需要20-30秒,我们一次做5个,顺序无关紧要。我的内存从来没有超过3.5Gb(总系统使用量),并且在运行后下降到1g以下。