Trying to Fix a Numpy Asscalar Deprecation Issue

While trying to update an old Python script I ran into the following error:

module 'numpy' has no attribute 'asscalar'. Did you mean: 'isscalar'?

Specifically:

def calibrate(x, y, z):
  # H = numpy.array([x, y, z, -y**2, -z**2, numpy.ones([len(x), 1])])
  H = numpy.array([x, y, z, -y**2, -z**2, numpy.ones([len(x)])])
  H = numpy.transpose(H)
  w = x**2
  
  (X, residues, rank, shape) = linalg.lstsq(H, w)
  
  OSx = X[0] / 2
  OSy = X[1] / (2 * X[3])
  OSz = X[2] / (2 * X[4])
  
  A = X[5] + OSx**2 + X[3] * OSy**2 + X[4] * OSz**2
  B = A / X[3]
  C = A / X[4]
  
  SCx = numpy.sqrt(A)
  SCy = numpy.sqrt(B)
  SCz = numpy.sqrt(C)
  
  # type conversion from numpy.float64 to standard python floats
  offsets = [OSx, OSy, OSz]
  scale = [SCx, SCy, SCz]
  
  offsets = map(numpy.asscalar, offsets)
  scale = map(numpy.asscalar, scale)
  
  return (offsets, scale)

I found that asscalar has been deprecated since NumPy 1.16. I found one reference that said to use numpy.ndarray.item, but I have no clue how to do that.

I did try this:

offsets = map.item(offsets)
scale = map.item( scale)

but got this error:

AttributeError: type object 'map' has no attribute 'item'

How can I solve this?

3

3 Answers

Temporary fix, worked in my case

import numpy

def patch_asscalar(a):
    return a.item()

setattr(numpy, "asscalar", patch_asscalar)
1

Just replace numpy.scalar using numpy.ndarray.item, that is, change

offsets = map(numpy.asscalar, offsets)
scale = map(numpy.asscalar, scale)

to

offsets = map(numpy.ndarray.item, offsets)
scale = map(numpy.ndarray.item, scale)
2

Assuming X is a 1d array with shape (6,), I created a dummy sample, and applied your calculations (thorough the first offsets)

X = np.array([1, 2.3, 3.2, .4,5.2, 3])

and got two lists of numpy scalars.

In [58]: offsets
Out[58]: [0.5, 2.8749999999999996, 0.3076923076923077]
In [59]: type(offsets[0])
Out[59]: numpy.float64

Looks like the map lines are Python 2, intended to produce lists of regular python floats. Python 3 would use list(map(...)).

item is a method of numpy scalars (and single item arrays). It could be used as:

In [60]: [OSx.item(), OSy.item(), OSz.item()]
Out[60]: [0.5, 2.8749999999999996, 0.3076923076923077]
In [61]: [i.item() for i in offsets]
Out[61]: [0.5, 2.8749999999999996, 0.3076923076923077]

One applies it to the OS values before they are collected in a list, the other uses a list comprehension (which is easier to use than map, at least for this).

Same for scale.

But for scale we don't need to take the sqrt individually; just make an array from the 3 values, apply sqrt to the whole array. Then use tolist() method to create a list of python floats. That's better than trying to do sqrt and item individually.

In [63]: np.sqrt(np.array([A,B,C]))
Out[63]: array([2.65491199, 4.19778444, 1.16425593])
In [64]: np.sqrt(np.array([A,B,C])).tolist()
Out[64]: [2.6549119933262744, 4.197784443104389, 1.1642559271506094]
1

Your Answer

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

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest