Ik heb zo’n 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()
En zo’n fout:
TypeError: only length-1 arrays can be converted to Python scalars
Hoe kan ik dit oplossen?
Antwoord 1, autoriteit 100%
De fout “alleen lengte-1-arrays kunnen worden geconverteerd naar Python-scalars” treedt op wanneer de functie een enkele waarde verwacht, maar u in plaats daarvan een array doorgeeft.
Als je naar de aanroephandtekening van np.int
kijkt, zul je zien dat deze een enkele waarde accepteert, geen array. Als je een functie wilt toepassen die een enkel element op elk element in een array accepteert, kun je in het algemeen 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()
Je kunt de definitie van f(x) overslaan en np.int gewoon doorgeven aan de vectorize-functie: f2 = np.vectorize(np.int)
.
Merk op dat np.vectorize
slechts een gemaksfunctie is en in feite een for-lus. Dat zal inefficiënt zijn over grote arrays. Wanneer je de mogelijkheid hebt, gebruik dan echt gevectoriseerde functies of methoden (zoals astype(int)
zoals @FFT suggereert).
Antwoord 2, autoriteit 36%
Gebruik:
x.astype(int)
Hier is de referentie.
Antwoord 3, autoriteit 3%
dataframe['column'].squeeze()
zou dit moeten oplossen. Het verandert in feite de dataframekolom in een lijst.
Antwoord 4, autoriteit 2%
Let op wat er wordt afgedrukt voor x
. U probeert een array (in feite gewoon een lijst) om te zetten in een int. length-1
zou een array van een enkel getal zijn, waarvan ik aanneem dat numpy het gewoon als een float behandelt. Je zou dit kunnen doen, maar het is geen louter nutteloze oplossing.
EDIT: ik was een paar weken geleden betrokken bij een post waarin numpy langzamer was dan ik had verwacht en ik realiseerde me dat ik in een standaardmindset was terechtgekomen dat numpy altijd de beste keuze was voor snelheid. Omdat mijn antwoord niet zo zuiver was als dat van ayhan, dacht ik dat ik deze ruimte zou gebruiken om te laten zien dat dit weer zo’n voorbeeld is om te illustreren dat vectorize
ongeveer 10% langzamer is dan het bouwen van een lijst in Python. Ik weet niet genoeg over numpy om uit te leggen waarom dit het geval is, maar misschien iemand anders?
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