6

I'm using scipy's loadmat function to load a matlab data file into python.

from scipy.io import loadmat  

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

The type of fields is 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,)

I iterate over the array using 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:

If I try to access the first element of x I get an 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

Questions:

  • How come, if type(x) returns nump.ndarray it says "too many indices for array"?
  • How can I extract the contents of x into a string?

Here are the versions I'm using:

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
3
  • Can you print out x.shape? Commented Jun 23, 2016 at 16:20
  • @C_Z_ - updated the question to include x.shape, which returns () Commented Jun 23, 2016 at 16:33
  • 1
    That's a 0d array, which you must index with a 0 element tuple, x[()]. See my answer. Commented Jun 23, 2016 at 16:35

1 Answer 1

12

Without looking at your errors in detail I can point out some pitfalls.

The .mat will contain MATLAB matrices (always 2d or higher), cells and structures.

loadmat renders those in various ways. There are dictionaries that you have to index by name. There are object arrays (dtype=object). And there are nd numeric or string arrays. You may have to work through several levels to get at the numeric array.

Check the 'shape' (size) of an array and its 'dtype'. If shape is () and dtype object, then extract it with y=x[()].

Here's an example of such a 0d object array:

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 is a 0d array (x.ndim), so it must be indexed with a 0 element tuple, (). For a MATLAB programmer that can seem odd.

In numpy (Python in general), x[a,b,c] is the same as x[(a,b,c)] and ind=(a,b,c); x[ind]. In other words, the arguments in [] are understood to be a tuple of values. (1,2) is a 2 element tuple, (1,) is one element ( (1) is just a grouping), and () is a 0 element tuple. So x[()] is just an extension of the regular nd indexing notation. It isn't a special case.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, using that array indexing notation (x[()]) worked. Do you have a resource where I can read up on that notation? I've never seen that before.
I added a paragraph on this notation.
x.item() is another way of extracting this single item.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.