2012-06-15 1 views
1

Я использую следующий код, чтобы попытаться загрузить файл MAT в Python. Я могу загрузить его без проблем в MATLAB.Почему загрузчик SciPy бросает MemoryError при чтении структуры Matlab на 200 МБ

from scipy.io import loadmat 
test_filename = 'test_data.mat' #This is a struct 
data =loadmat(test_filename, struct_as_record=True) 

Запуск этого кода производит эту ошибку:

Traceback (most recent call last): 
    File "C:\Users\mac389\workspace\nexUtils\src\qA.py", line 16, in <module> 
data =loadmat(test_filename, struct_as_record=True) 
    File "C:\Python27\lib\site-packages\scipy\io\matlab\mio.py", line 175, in loadmat 
matfile_dict = MR.get_variables(variable_names) 
    File "C:\Python27\lib\site-packages\scipy\io\matlab\mio5.py", line 272, in get_variables 
hdr, next_position = self.read_var_header() 
    File "C:\Python27\lib\site-packages\scipy\io\matlab\mio5.py", line 224, in read_var_header 
stream = BytesIO(dcor.decompress(data)) 
MemoryError 

Для справки, test_data.mat является структурой со следующими полями (из MATLAB консоли):

version: 101 
comment: 'molecular layer 4/17' 
    freq: 40000 
    tbeg: 0 
    tend: 1.3950e+003 
    events: {3x1 cell} 
neurons: {50x1 cell} 
    waves: {102x1 cell} 
contvars: {64x1 cell} 

Test_data.mat составляет 217 МБ. У меня 4 ГБ ОЗУ. Я использую SciPy 0.10.0 и NumPy 1.6.1. Изменение поля 'struct_as_record' ничего не делает.

Как я могу загрузить структуру, где поля являются массивами ячеек?

+0

У вас закончилась память. Хотя файл может быть только 200 МБ, требования к памяти могут быть значительно больше. –

+0

Сжат ли файл .mat? Является ли процесс Python 32-битным? Является ли ваш процесс MATLAB 64-битным? –

+0

@David: Файл мата больше не сжат за двоичным форматом Matlab. Оба процесса 32 бит. Мой вопрос в том, почему загрузка небольшого файла сбрасывает память в Python, но не в Matlab, и что я могу сделать, чтобы обойти это. – mac389

ответ

2

Я нашел ответ.

Loadmat не может иметь дело с сильно вложенными структурами. В наборе данных, который я дал, три из структурных полей: «волны, нейроны, контрмеры» были массивами ячеек. Каждый член этого массива ячеек был структурой. Некоторые из полей этих структур были самими массивами ячеек. Эти ячейки имели одно поле, содержащее данные. Этот нестандартный способ организации данных в сочетании с отсутствием документации создал проблему.

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

1

Я думаю, что на Python требуется больше памяти из-за того, как реализована декомпрессия. Попробуйте сохранить в Matlab без сжатия (используя -v6, формат версии 6 не имеет функции сжатия).

+0

Это поможет определить, является ли проблема памятью. Спасибо за полезное диагностическое предложение. Но что делать тогда? – mac389

+1

Хорошо, что вы не можете сделать. Если он работает, вы можете использовать v6 на стороне Matlab (вы можете установить его как формат сохранения по умолчанию). В противном случае вам потребуется обновить память на стороне Python и переключиться на 64 бит. Или вы можете посмотреть на использование другого формата. Matlab может записывать на HDF5, который хорошо поддерживается в Python, поэтому, если вы можете преобразовать свои данные в соответствии с контейнером HDF5, возможно, это сработает для вас. – robince