How to fix Python error – “only size 1 arrays can be converted to python scalars”

How to fix Python error – “only size 1 arrays can be converted to python scalars”

You’ve encountered a python TypeError that looks something like this:

What does this python TypeError mean? Why are you getting it? How can you solve it? This article will answer all these questions.

What does python TypeError mean?

The error you’ve encountered is a TypeError. The “Type” here refers to data types. Thus, this error means that you’ve used a variable with the wrong data type somewhere in your program. This may have happened when passing a variable to a function that doesn’t accept such a data type as input. Specifically, the error indicates that you passed an array (of size not equal to 1), into a function that accepts only single values. Since the TypeError specifically talks about arrays (and not lists), this error is associated with modules like NumPy, that allow us to define fixed-size arrays in Python.

Why are you getting python TypeError?

Let’s see a common example of where you could get such a python TypeError. Say you have an array of numbers that are written as strings. You would like to convert each of these numerical strings into an integer. To do this, you write the following code:

import numpy as np
a = np.array(["1","2","3"]) #the input array

x = int(a)
print(x)Code language: Python (python)

You expected that the variable x would now point to an array that has the same values as an array a but typecasted to the integer datatype. However, you receive an error message:

This is the same error we’ve been talking about. The fault in the code here is that the function int only works on a single input, not on a sequence of inputs. Thus, you cannot directly pass the array a to the function int and expect it to typecast all items of the array. You will have to find another way.

How can you solve python TypeError?

The error arises when we try to use a function meant for single values (one item) on an entire array (list of items). This often happens when we want to apply the function to each array item. To solve this error we need to respect the constraint that the function can only work on single items and find a way to apply the function to each item in the array. There are many ways to do this.

Using a for loop

This is the most basic way to solve this problem. Apply the function on each item of the array using a loop. Store the results in a list. In case you want your result as an array, convert the list into an array.

The code below uses this technique to solve our example:

import numpy as np
a = np.array(["1","2","3"])

x = []
for item in a:
    x.append( int(item) )

x = np.array(x)
print(x)Code language: Python (python)

We (temporarily) define a list pointed to by the variable x. We iterate through the array a, and for each element, we typecast it to an integer. We store this result in the list x. Finally, we can convert our list x into a NumPy array. This gives us the correct output:

Using np.vectorize

The NumPy module has an inbuilt function called vectorize. This function takes as input any python function and returns a vectorized callable function. This new function can now be used on arrays directly. It will apply the python function to each element of the array and return an array of outputs. The order of the outputs of the elements in the new array will be the same as the order of the elements in the original array.
Let’s see how we can use this to solve our example:

import numpy as np
a = np.array(["1","2","3"])

int_func = np.vectorize(int)
x = int_func(a)

print(x)Code language: Python (python)

In the code above, we have created a vectorized callable function int_func that can apply the python function int on a sequence of items directly. We call this function int_func directly on the array a, and the output is the required array x. Observe how the order is conserved:

An important point to note is that np.vectorize simply uses a for loop in the background. The only difference from Method 1 is that it allows us to directly define a function that can be used on arrays instead of having to write a for loop manually. This is particularly helpful when we need to use such a function multiple times.

Using inbuilt map() function

Python provides an inbuilt function, map(func, iterable), that is used to apply the function func to every item in the set of items iterable. An iterable in Python is any data structure that contains a set of values. Lists, sets, and dictionaries are common examples of iterables.
The output of the map function is a map object. This object can be converted to any iterable like list or set using inbuilt python functions. Let’s see how we can use the map function to solve our example:

import numpy as np
a = np.array(["1","2","3"])

map_obj = map(int, a)
x = list(map_obj)

x = np.array(x)
print(x)Code language: Python (python)

We use the map function by passing the int function and the array a to it. It returns a map object which we store in the variable map_obj. We then use the list() function to convert the map object into a list and store this in our variable x. Since we prefer our final output to be an array rather than a list, we convert the list x into an array using NumPy. Our desired output is shown below:

Although it may seem like this method has a few additional steps like converting the map object into a list, this method is more efficient than the previous two methods that we have discussed. This is because the internal implementation of the map function is faster than using a for loop to iterate through the elements and apply the function to each element.

Using NumPy’s astype() function

The astype function is a much easier function to use in practice than the other methods we have seen. It doesn’t require you to explicitly write a for loop or to make a vectorized callable function. It can simply do what we need in one line of code. However, it does have limitations as it can only be used for typecasting rather than applying any function to all items of an array.

Let’s solve our example using the astype function:

import numpy as np
a = np.array(["1","2","3"]) #the input array
x = a.astype(int)

print(x)Code language: Python (python)

We pass a required datatype to the astype function. It returns an array with all items from the original array typecasted to that datatype. Thus, the list x is our required answer.

Size 1 arrays – Special case

Python can automatically convert size 1 arrays to single items (a.k.a scalars). Thus, even if we pass an array with size 1 to a function that only takes single items as input, we do not get an error. Consider the example below:

import numpy as np
a = np.array(["1"]) #the input array

x = int(a)
print(x)Code language: Python (python)

Since the array a just has a single element, python converts it into a scalar when the int function is called on it. Thus, we do not get any errors. However, the variable x doesn’t point to an array now. It stores a single value. This is clear from the output below:

x is an integer, not an array.

Conclusion

In this article, we’ve learned all about the python TypeError “only size 1 array can be converted to python scalars”. We’ve also discussed multiple solutions to this python TypeError. We’ve even covered the edge case of size 1 arrays.

Errors are inevitable in a programmer’s life. But understanding and finding solutions to these errors are what makes a great programmer.

Sharing is caring

Did you like what Astitva Sehgal wrote? Thank them for their work by sharing it on social media.

0/10000

No comments so far