Как получить доступ к элементам numpy ndarray?

6

Я использую функцию scipy loadmat для загрузки файла данных matlab в python.

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 комментарий
Теги:
arrays
numpy
scipy

1 ответ

6
Лучший ответ

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

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

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

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

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

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) является 2-элементным кортежем, (1,) является одним элементом ((1) является просто группировкой), а () является корневым элементом. Итак, x[()] является просто расширением регулярной нотации индексирования nd. Это не особый случай.

  • 0
    Спасибо, с помощью этой записи индексации массива ( x[()] ) сработало. У вас есть ресурс, где я могу прочитать эту запись? Я никогда не видел этого раньше.
  • 1
    Я добавил параграф на эту запись.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню