22

I am reading in a file using numpy.genfromtxt which brings in columns of both strings and numeric values. One thing I need to do is detect the length of the input. This is all fine provided there are more than one value read into each array.

But...if there is only one element in the resulting array, the logic fails. I can recreate an example here:

import numpy as np
a = np.array(2.3)

len(a) returns an error saying:

TypeError: len() of unsized object

however, If a has 2 or more elements, len() behaves as one would expect.

import numpy as np
a = np.array([2.3,3.6])

len(a) returns 2

My concern here is, if I use some strange exception handling, I can't distinguish between a being empty and a having length = 1.

EDIT: @noskio suggested setting a = np.array([2.3]). The problem is, the actual genesis of a is by using numpy.genfromtxt. The code looks like this:

import numpy as np
indata = np.genfromtxt(some_filename, names=True,dtype=None)
a = indata['one_col_headername']

As a result, if indata is only one row in the file, a is a 0-d array.

1
  • 1
    array([2]) is an array with one element and 1 dimension. array(2) is an array with zero rank or zero dimensions. Commented Dec 16, 2012 at 5:12

5 Answers 5

41

If you need a one-liner (assuming the answer you are expecting is 1):

In [1]: import numpy as np

In [2]: a = np.array(2.3)

In [3]: len(np.atleast_1d(a))
Out[3]: 1

This page explains why it was decided to implement 0-dimensional arrays in numpy.

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

1 Comment

@wim it looks like the link has been removed, and I cannot find a replacement for it.
6
import numpy as np

tests=[np.array(2.3),np.array([]),np.array([2.3]),np.array([2.3,3.6])]

print('{a:30}{s:<10}{l:<10}{sl:<10}'.format(a='repr',s='shape',sl='len(shape)',l='length'))
for a in tests:
    s=a.shape
    l=len(a) if a.shape else 0
    sl=len(s)
    print('{a!r:30}{s:<10}{l:<10}{sl:<10}'.format(a=a,l=l,s=s,sl=sl))

yields

repr                          shape     length    len(shape)
array(2.2999999999999998)     ()        0         0         
array([], dtype=float64)      (0,)      0         1         
array([ 2.3])                 (1,)      1         1         
array([ 2.3,  3.6])           (2,)      2         1        

You can distinguish between an "empty" array (e.g. np.array([])) and a numpy scalar (e.g. np.array(2.3)) by looking at the length of the shape.

1 Comment

Thanks @unubtu. That's cool, but how can I distinguish between a with length of 1 and an empty a?
3

It looks like the size property of ndarrays will work in this case if you know that the array is one-dimensional. In my opinion, a.size is a lot more readable than len(np.atleast_1d(a)). However, note that the size property will return the total number of elements in the array if it has more than one dimension:

In [1]: import numpy as np

In [2]: np.array(2.3).size
Out[2]: 1

In [3]: np.array([1, 2]).size
Out[3]: 2

In [4]: np.array([[1,2], [3,4]]).size
Out[4]: 4

Comments

0
a = np.array([2.3])
print len(a)

1 Comment

this works for a constant as you show, but not for an array input
0

Had this same issue, I found a simple way to distinguish the two use cases mentioned by mishaF and leoschet:

    import numpy as np
    array_1=np.array(2.3) #not in a list
    array_2=np.array([2.3]) #in a list of len 1
    print(len(array_1)) #gives the type error mentioned in the question
    print(len(array_2)) #returns 1 as desired

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.