2014-01-06 3 views
6

Я решил использовать memmapfile, потому что мои данные (обычно от 30 ГБ до 60 ГБ) слишком велики, чтобы вписаться в память компьютера.Файл карты памяти в MATLAB?

Мои файлы данных состоят из двух столбцов данных, соответствующих выходам двух датчиков, и я их в обоих форматах .bin и .txt.

m=memmapfile('G:\E-Stress Research\Data\2013-12-18\LD101_3\EPS/LD101_3.bin','format','int32') 
m.data(1) 

Я использовал приведенный выше код к карте памяти моих данных в переменные «м», но я понятия не имею, какой формат данные для использования (INT8' , „Int16“, „int32“, „int64“,» uint8, uint16, uint32, uint64, single и double. На самом деле я пробовал все форматы данных, перечисленные в MATLAB, но когда я использовал m.data (индексный номер), я никогда не получал пару чисел (2 столбца данных), которые я ожидал, а также число будет быть разными в зависимости от формата, который я использовал.

Если у кого-то есть опыт работы с memmapfile, пожалуйста, помогите мне.

Here несколько уменьшенных версий моих файлов данные, чтобы люди могли понять, как структурировано мои данные:

веселит Джеймс

+0

Предполагая, что у вас есть простой двоичный файл, нет никакой структуры. Все данные просто записываются в строке, аналогичной «X (:)», преобразующей матрицу в вектор. У вас есть информация о том, как записывается двоичный файл? Если нет, попробуйте создать небольшие файлы .txt и .bin и загрузить их. – Daniel

+0

Похоже, что с помощью опции «Формат» вы можете указать «форму массива». –

+0

@ DanielR Я не знаю, как был записан двоичный файл, но я создал несколько относительно небольших файлов и загрузил их: https://www.dropbox.com/sh/rzut4zbrert9fm0/q9SiZYmrdG –

ответ

5

memmapfile предназначен для чтения двоичных файлов, поэтому у вас возникли проблемы с вашим текстовый файл. В данных есть символы, поэтому вам придется читать их как символы, а затем анализировать их на числа. Подробнее об этом ниже.

Бинарный файл, как представляется, содержит больше, чем просто поток значений с плавающей запятой, записанный в двоичном формате. Я вижу идентификаторы (строки) и другие вещи в файле. Ваша единственная надежда на чтение - связаться с производителем устройства, создавшего двоичный файл, и спросить их о том, как читать в таких файлах. Вероятно, будет SDK или, по крайней мере, описание формата. Вы можете посмотреть на это, поскольку числа с плавающей точкой в ​​вашем текстовом файле могут быть усечены, т. Е. Вы потеряли точность по сравнению с прямым чтением двоичного представления поплавков.

Итак, как читать файл с помощью memmapfile? This post содержит некоторые подсказки.

Итак, сначала мы открываем файл в 'uint8' (примечание нет 'char' вариант, так как обходной путь мы читаем содержимое файла в тип данных одного и того же размера):

m = memmapfile('RTL5_57.txt','Format','uint8'); % uint8 is default, you could leave that off 

Мы можем оказать считывание данных в качестве uint8 как символы литья его обугливаются:

c = char(m.Data(1:19)).' % read the first three lines. NB: transpose just for getting nice output, don't use it in your code 
c = 
    0.398516 0.063440 
    0.399611 0.063284 
    0.398985 0.061253 

поскольку каждая строка в файле имеет ту же длину (2 * 8 символов для чисел, 1 вкладка и 2 символа для перевода строки = 19 символов), мы можем читать N строк из файл, считывая значения N*19. Итак, m.Data(1:19) доставит вам первую строку, m.Data(20:38), вторую строку и m.Data(20:57) вторую и третью строки. Прочитайте столько, сколько хотите.

Тогда мы должны будем анализировать данные для чтения в в числа с плавающей точкой:

f = sscanf(c,'%f') 
f = 
    0.3985 
    0.0634 
    0.3996 
    0.0633 
    0.3990 
    0.0613 

Все, что осталось сделать, это изменить их в формате две колонки

d = reshape(f,2,[]).' 
d = 
    0.3985 0.0634 
    0.3996 0.0633 
    0.3990 0.0613 

Легче пути использования memmapfile: Для решения проблемы не нужно использовать memmapfile, и я думаю, что это усложняет ситуацию. Вы можете просто использовать fopen с последующим fread:

fid = fopen('RTL5_57.txt'); 
c = fread(fid,Nlines*19,'*char'); 
% now sscanf and reshape as above 
% NB: one can read the values the text file directly with f = fscanf(fid,'%f',Nlines*19). 
% However, in testing, I have found calling fread followed by sscanf to be faster 
% which will make a significant difference when reading such large files. 

С помощью этого вы можете прочитать Nlines пар значений, в то время, обрабатывать их и просто вызвать fread снова прочитать следующую Nlines. fread запоминает, где он находится в файле (как и fscanf), поэтому просто используйте тот же вызов, чтобы получить следующие строки. Таким образом, легко написать цикл для обработки всего файла, тестирование с помощью feof(fid), если вы находитесь в конце файла.

Предлагается еще более простой способ: here: использовать textscan. Чтобы немного адаптировать их пример кода:

Nlines = 10000; 

% describe the format of the data 
% for more information, see the textscan reference page 
format = '%f\t%f'; 

fid = fopen('RTL5_57.txt'); 

while ~feof(fid) 
    C = textscan(fid, format, Nlines, 'CollectOutput', true); 
    d = C{1}; % immediately clear C at this point if you need the memory! 
    % process d 
end 

fclose(fid); 

Примечание снова, однако, что fread затем sscanf будет самым быстрым. Обратите внимание, однако, что метод fread умрет, как только в текстовом файле будет одна строка, которая точно не соответствует вашему формату. textscan с другой стороны прощает изменения пробелов и, следовательно, более прочные.

+0

Спасибо, что ответили, что он был действительно всеобъемлющим и полезным. –

Смежные вопросы