2016-06-23 3 views
6

Я использую функцию scipy's loadmat для загрузки файла данных matlab в python.Как получить доступ к элементам numpy ndarray?

from scipy.io import loadmat 

data = loadmat('data.mat') 
fields = data['field'] 

Тип fields является numpy.ndarray:

print 'fields type={}'.format(type(fields)) 
print 'fields dtype={}'.format(fields.dtype) 
print 'fields shape={}'.format(fields.shape) 
fields type=<type 'numpy.ndarray'> 
fields dtype=object 
fields shape=(5,) 

я итерации по массиву с помощью nditer:

for x in np.nditer(fields, flags=['refs_ok']): 
    print 'x={}'.format(x) 
    print 'x type={}'.format(type(x)) 
    print 'x dtype={}'.format(x.dtype) 
    print 'x shape={}'.format(x.shape) 
    break 
x=[u'ACE'] 
x type=<type 'numpy.ndarray'> 
x dtype=object 
x shape=() 

IndexError:

Если я пытаюсь получить доступ к первому элементу x я получаю IndexError:

x[0] 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-102-8c374ae22096> in <module>() 
    17  print 'type={}'.format(type(x)) 
    18  print 'dtype={}'.format(x.dtype) 
---> 19  x[0] 
    20  break 
    21 

IndexError: too many indices for array 

Вопросы:

  • Как приходят, если type(x) возвращает nump.ndarray он говорит «слишком много индексов для массива»?
  • Как я могу извлечь содержимое x в строку?

Вот версии я использую:

print 'python version: {}'.format(sys.version) 
print 'numpy version: {}'.format(numpy.__version__) 
print 'scipy version: {}'.format(scipy.__version__) 
python version: 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] 
numpy version: 1.11.0 
scipy version: 0.17.1 
+0

Можете ли вы распечатать 'x.shape'? –

+0

@C_Z_ - обновил вопрос, включив в него 'x.shape', который возвращает'() ' –

+1

Это массив 0d, который вы должны индексировать с помощью кортежа 0 элементов' x [()] '. См. Мой ответ. – hpaulj

ответ

6

Не смотря на ваши ошибки в деталях, я могу указать на некоторые подводные камни.

. .mat будет содержать матрицы MATLAB (всегда 2d или выше), ячейки и структуры.

loadmat оказывает их различными способами. Есть словари, которые вы должны индексировать по имени. Существуют объектные массивы (dtype = object). И есть числовые или строковые массивы. Возможно, вам придется работать через несколько уровней, чтобы получить числовой массив.

Проверьте 'форму' (размер) массива и его 'dtype'. Если форма () и dtype объект, то извлеките его y=x[()].

Вот пример такого массива 0дн объекта:

In [4]: y=np.arange(3) 

In [5]: x=np.empty((), dtype=object)  
In [6]: x[()]=y 

In [7]: x 
Out[7]: array(array([0, 1, 2]), dtype=object) 

In [8]: x.shape 
Out[8]:() 

In [9]: x.dtype 
Out[9]: dtype('O') 

In [10]: x[0] 
... 
IndexError: too many indices for array 

In [11]: x[()] 
Out[11]: array([0, 1, 2]) 

x является 0d массив (x.ndim), поэтому он должен быть индексированы 0 элемент кортежа а, (). Для программиста MATLAB, который может показаться странным.

В numpy (Python в целом), x[a,b,c] - это то же самое, что и x[(a,b,c)] и ind=(a,b,c); x[ind]. Другими словами, аргументы в [] понимаются как набор значений.(1,2) является двухэлементным кортежем, (1,) является одним из элементов ((1) - это всего лишь группировка), а () является корневым элементом 0. Таким образом, x[()] является просто расширением регулярной нотации индекса nd. Это не особый случай.

+0

Спасибо, используя эту нотацию индексации массива ('x [()]'). У вас есть ресурс, где я могу читать эту нотацию? Я этого раньше не видел. –

+1

Я добавил абзац об этом обозначении. – hpaulj

+0

Получил это, спасибо за объяснение! –