I have such Python code:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.int(x)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f(x))
plt.show()
And such error:
TypeError: only length-1 arrays can be converted to Python scalars
How can I fix it?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The error “only length-1 arrays can be converted to Python scalars” is raised when the function expects a single value but you pass an array instead.
np.int was an alias for the built-in int, which is deprecated in numpy v1.20. The argument for int should be a scalar and it does not accept array-like objects. In general, if you want to apply a function to each element of the array, you can use np.vectorize:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return int(x)
f2 = np.vectorize(f)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f2(x))
plt.show()
You can skip the definition of f(x) and just pass the function int to the vectorize function: f2 = np.vectorize(int).
Note that np.vectorize is just a convenience function and basically a for loop. That will be inefficient over large arrays. Whenever you have the possibility, use truly vectorized functions or methods (like astype(int) as @FFT suggests).
Method 2
Use:
x.astype(int)
Here is the reference.
Method 3
dataframe['column'].squeeze() should solve this. It basically changes the dataframe column to a list.
Method 4
Take note of what is printed for x. You are trying to convert an array (basically just a list) into an int. length-1 would be an array of a single number, which I assume numpy just treats as a float. You could do this, but it’s not a purely-numpy solution.
EDIT: I was involved in a post a couple of weeks back where numpy was slower an operation than I had expected and I realised I had fallen into a default mindset that numpy was always the way to go for speed. Since my answer was not as clean as ayhan’s, I thought I’d use this space to show that this is another such instance to illustrate that vectorize is around 10% slower than building a list in Python. I don’t know enough about numpy to explain why this is the case but perhaps someone else does?
import numpy as np
import matplotlib.pyplot as plt
import datetime
time_start = datetime.datetime.now()
# My original answer
def f(x):
rebuilt_to_plot = []
for num in x:
rebuilt_to_plot.append(np.int(num))
return rebuilt_to_plot
for t in range(10000):
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f(x))
time_end = datetime.datetime.now()
# Answer by ayhan
def f_1(x):
return np.int(x)
for t in range(10000):
f2 = np.vectorize(f_1)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f2(x))
time_end_2 = datetime.datetime.now()
print time_end - time_start
print time_end_2 - time_end
Method 5
In this case the output has to be a rounded int values.
import numpy as np
arr = np.array([2.34, 2.56, 3.12])
output = np.round(arr).astype(int)
print(output)
# array([2, 3, 3])
Method 6
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.array(list(map(np.int, x)))
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f(x))
plt.show()
using np.array(list(map(np.int, x))) will converge numpy array to scaler value and fix the issue for more detail visit this detailed article.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0