94

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?

6 Answers 6

104

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).

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

5 Comments

Cleaner and I imagine also faster (I should test). I still have to learn the learn the intricacies of numpy for things like this :)
Interestingly enough, my answer appears to be faster and I gave the reasoning behind investigation but I don't know the true reason for performance difference. Perhaps someone will shed some light :)
np.int is just a confusing way to spell int. Never use the former. Your code can be simplified to f = int.
@ayhan: What if I want to convert numpy array to an object , which I can insert into MongoDB is pickling the way to go ahead?
np.int() is deprecated.
45

Use:

x.astype(int)

Here is the reference.

1 Comment

This answer works compared to the accepted answer, np.int() is deprecated.
4

dataframe['column'].squeeze() should solve this. It basically changes the dataframe column to a list.

Comments

1

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

Comments

1

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])

Comments

1
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.

Comments

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.