Python 使用数组和多个参数进行多处理
Python multiprocessing with arrays and multiple arguments
所以我试图读入一堆非常大的数据文件,每个文件都需要相当长的时间来加载。我试图弄清楚如何以最快的方式加载它们并且不会 运行 进入内存问题。一旦数据文件以正确的方式加载到数组中,我就不需要写入它们,而只需要读取。一段时间以来,我一直在尝试将其并行化,但无法弄清楚。
假设我有 400 个时间文件。这些文件中的每一个都是制表符分隔的,并且有 30 个变量,每个变量有 40,000 个数据点。我想创建一个 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 函数,但其中 none 似乎喜欢我的数组。
我对这种方法不是一成不变。如果有更好的方法来做到这一点,我将不胜感激。一次加载所有这些数据将花费太长时间。我的计算表明,使用一个内核在我的计算机上加载需要大约 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 文件的时间延迟)。我将选项 low_memory=False
添加到 read_csv
命令,因为它使它运行得更快。 j 循环真的很快,所以我不需要加快它的速度。
现在每个 LoadTimeFile
循环大约需要 20-30 秒,我们一次做 5 个,顺序无关紧要。我的 ram 从未超过 3.5Gb(系统总使用量)并在运行后回落到 gig 以下。
所以我试图读入一堆非常大的数据文件,每个文件都需要相当长的时间来加载。我试图弄清楚如何以最快的方式加载它们并且不会 运行 进入内存问题。一旦数据文件以正确的方式加载到数组中,我就不需要写入它们,而只需要读取。一段时间以来,我一直在尝试将其并行化,但无法弄清楚。
假设我有 400 个时间文件。这些文件中的每一个都是制表符分隔的,并且有 30 个变量,每个变量有 40,000 个数据点。我想创建一个 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 函数,但其中 none 似乎喜欢我的数组。
我对这种方法不是一成不变。如果有更好的方法来做到这一点,我将不胜感激。一次加载所有这些数据将花费太长时间。我的计算表明,使用一个内核在我的计算机上加载需要大约 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 文件的时间延迟)。我将选项 low_memory=False
添加到 read_csv
命令,因为它使它运行得更快。 j 循环真的很快,所以我不需要加快它的速度。
现在每个 LoadTimeFile
循环大约需要 20-30 秒,我们一次做 5 个,顺序无关紧要。我的 ram 从未超过 3.5Gb(系统总使用量)并在运行后回落到 gig 以下。