У меня есть файлы данных, которые содержат данные для многих временных интервалов, причем каждый временной интервал отформатирован в виде блока, подобного этому:
TIMESTEP PARTICLES
0.00500103 1262
ID GROUP VOLUME MASS PX PY PZ VX VY VZ
651 0 5.23599e-07 0.000397935 -0.084626 -0.0347849 0.00188164 0 0 -1.04903
430 0 5.23599e-07 0.000397935 -0.0837742 -0.0442293 0.0121046 0 0 -1.04903
384 0 5.23599e-07 0.000397935 -0.0749234 -0.0395652 0.0143401 0 0 -1.04903
971 0 5.23599e-07 0.000397935 -0.0954931 -0.0159607 0.0100155 0 0 -1.04903
....
Каждый блок состоит из 3 строк заголовка и нескольких строк данных, относящихся к временному шагу (int в строке 2). Количество строк данных, связанных с блоком, может варьироваться от 0 до 10 миллионов. Между каждым блоком может быть пустая строка, но иногда она отсутствует.
Я хочу иметь возможность читать файл блок за блоком, обрабатывая данные после чтения блока - файлы большие (часто более 200 ГБ), и один временной шаг - это все, что можно удобно загрузить в память.
Из-за формата файла я подумал, что будет довольно легко написать функцию, которая считывает 3 строки заголовка, считывает фактические данные, а затем возвращает хороший массив numpy для обработки данных. Я привык к MATLAB, где вы можете просто читать по блокам, а не в конце файла. Я не совсем уверен, как это сделать с помощью python.
Я создал следующую функцию для чтения блока данных:
def readBlock(f):
particleData = []
Timestep = []
numParticles = []
linesProcessed = 0
line = f.readline().strip()
if line.startswith('TIMESTEP'):
timestepHeaders = line.strip()
varData = f.readline().strip()
headerStrings = f.readline().strip().split(' ')
parts = varData.strip().split(' ')
Timestep = float(parts[0])
numParticles = int(parts[1])
while linesProcessed < numParticles:
particleData.append(tuple(f.readline().strip().split(' ')))
linesProcessed += 1
mydt = np.dtype([ ('ID',int),
('GROUP', int),
('Vol', float),
('Mass', float),
('Px', float),
('Py', float),
('Pz', float),
('Vx', float),
('Vy', float),
('Vz', float),
] )
particleData = np.array(particleData, dtype=mydt)
return Timestep, numParticles, particleData
Я пытаюсь запустить функцию следующим образом:
with open(fileOpenPath, 'r') as file:
startWallTime = time.clock()
Timestep, numParticles, particleData = readBlock(file)
print(Timestep)
## Do processing stuff here
print("Timestep Processed")
endWallTime = time.clock()
Проблема в том, что он читает только первый блок данных из файла и останавливается на этом - я не знаю, как заставить его перебирать файл, пока он не достигнет конца и не остановится.
Любые предложения о том, как сделать эту работу, были бы замечательными. Я думаю, что могу написать способ сделать это, используя однострочную обработку с большим количеством проверок if, чтобы увидеть, нахожусь ли я в конце временного шага, но простая функция казалась проще и понятнее.