TypeError: solo los arrays de longitud 1 se pueden convertir a escalares de Python mientras se muestra la ttwig

Tengo tal código Python:

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

Y tal error:

 TypeError: only length-1 arrays can be converted to Python scalars 

¿Cómo puedo arreglarlo?

El error “solo las matrices de longitud 1 se pueden convertir a escalares de Python” se genera cuando la función espera un valor único, pero en su lugar se pasa una matriz.

Si observa la firma de llamada de np.int , verá que acepta un solo valor, no una matriz. En general, si desea aplicar una función que acepte un solo elemento a cada elemento de una matriz, puede usar np.vectorize :

 import numpy as np import matplotlib.pyplot as plt def f(x): return np.int(x) f2 = np.vectorize(f) x = np.arange(1, 15.1, 0.1) plt.plot(x, f2(x)) plt.show() 

Puede omitir la definición de f (x) y simplemente pasar np.int a la función vectorizar: f2 = np.vectorize(np.int) .

Tenga en cuenta que np.vectorize es solo una función de conveniencia y básicamente un bucle for. Eso será ineficiente en grandes arreglos. Siempre que tenga la posibilidad, use funciones o métodos verdaderamente vectorizados (como astype(int) como sugiere @FFT ).

Utilizar:

 x.astype(int) 

Aquí está la referencia .

Tome nota de lo que está impreso para x . Está intentando convertir una matriz (básicamente solo una lista) en un int. length-1 sería una matriz de un solo número, que supongo que numpy simplemente trata como un flotador. Puedes hacer esto, pero no es una solución puramente numérica.

EDITAR: Estuve involucrado en una publicación hace un par de semanas, donde el número fue una operación más lenta de lo que esperaba y me di cuenta de que había caído en la mentalidad predeterminada de que el número siempre era el camino a seguir para la velocidad. Ya que mi respuesta no fue tan clara como la de ayhan, pensé que usaría este espacio para mostrar que este es otro ejemplo para ilustrar que la vectorize es aproximadamente un 10% más lenta que crear una lista en Python. No conozco lo suficiente para explicar por qué este es el caso, pero tal vez alguien más lo sepa.

 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