Indexing NumPy arrays with floats …

… now you can’t.

I recently updated to the latest version of NumPy (1.12.1), and today I discovered that some of my spreadsheets using NumPy arrays (via xlwings) were returning errors like:

IndexError: only integers, slices (`:`), ellipsis (`…`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

The problem was that using floats to index NumPy arrays previously generated a warning, but now generates an error:

DeprecationWarning to error
•Indexing with floats raises IndexError, e.g., a[0, 0.0].
•Indexing with non-integer array_like raises IndexError, e.g., a[‘1’, ‘2’]
•Indexing with multiple ellipsis raises IndexError, e.g., a[…, …].
•Non-integers used as index values raise TypeError, e.g., in reshape, take, and specifying reduce axis

You might ask, why use floats to index an array in the first place?  The reason is that if a range is copied from Excel to Python then by default all the values are passed as float64.  The array could be converted to all integers, but if the values are mixed integers and floats (such as an array of node numbers and coordinates) that won’t work.  In previous versions the values to be used as array indices could just be left as floats, but now it is necessary to convert them to integers before using them as index values.

I will be working through my Python code posted here and update as required, but if you come across an IndexError anywhere, please let me know.

This entry was posted in Arrays, Excel, Link to Python, NumPy and SciPy, UDFs, VBA and tagged , , , , , . Bookmark the permalink.

2 Responses to Indexing NumPy arrays with floats …

  1. Ana Sofía's avatar Ana Sofía says:

    hi, i’ve got that problem
    i’m working with an array of nodes and coordinates and my code is kinda like this
    import numpy as np
    nodos= np.loadtxt(“valle_aburra.pts”)
    print (nodos)
    con= np.loadtxt(“triangulos.tri”)
    x= nodos[:,0]
    y=nodos[:,1]
    z=nodos[:,2]
    v=[]
    areatotal=[]
    nf,nc= np.shape(nodos)
    for i in range (0,nf):
    l=nodos[i]
    x1=(x[l[0]])
    y1=float(y[l[0]])
    x2=float(x[l[1]])
    y2=float(y[l[1]])
    d=((x1-x1)**2+(y1-y2)**2)**(1/2)
    v.append(d)

    x1=float(x[l[1]])
    y1=float(y[l[1]])
    x2=float(x[l[2]])
    y2=float(y[l[2]])
    d=((x1-x1)**2+(y1-y2)**2)**(1/2)
    v.append(d)

    x1=float(x[l[2]])
    y1=float(y[l[2]])
    x2=float(x[l[0]])
    y2=float(y[l[0]])
    d=((x1-x1)**2+(y1-y2)**2)**(1/2)
    v.append(d)

    s=(v[0]+v[2]+v[3])/2 #formula de herón para las áreas de un triangulo
    area=(s(s-v[0])(s-v[1])(s-v[2]))**(1/2)
    areatotal=areatotal+area

    but it gives me an error that says

    x1=(x[l[0]])
    IndexError: only integers, slices (`:`), ellipsis (`…`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
    i’m new in python so it’s causing me some trouble to do this, i’ll aprecciate if u could help me.
    thanks.

    Like

    • dougaj4's avatar dougaj4 says:

      For your case the easiest way would be to import the list of nodes as numpy integers:
      nodos= np.loadtxt(“valle_aburra.pts”, dtype=np.int)

      If for some reason you had to import the numbers as floats (if your data included coordinates and node numbers on each line for instance) you can convert the number to an integer when you use it:
      l = np.int(nodos[I])
      or:
      x1 = x[np.int(l[0]]

      Also see: https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.loadtxt.html
      for more options with loadtxt.

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.