Służy val.item()
do konwersji większości wartości NumPy na rodzimy typ Pythona:
import numpy as np
# for example, numpy.float32 -> python float
val = np.float32(0)
pyval = val.item()
print(type(pyval)) # <class 'float'>
# and similar...
type(np.float64(0).item()) # <class 'float'>
type(np.uint32(0).item()) # <class 'long'>
type(np.int16(0).item()) # <class 'int'>
type(np.cfloat(0).item()) # <class 'complex'>
type(np.datetime64(0, 'D').item()) # <class 'datetime.date'>
type(np.datetime64('2001-01-01 00:00:00').item()) # <class 'datetime.datetime'>
type(np.timedelta64(0, 'D').item()) # <class 'datetime.timedelta'>
...
(Inna metoda jest np.asscalar(val)
jednak przestarzała od NumPy 1.16).
Dla ciekawskich, aby zbudować tabelę konwersji skalarów tablicowych NumPy dla twojego systemu:
for name in dir(np):
obj = getattr(np, name)
if hasattr(obj, 'dtype'):
try:
if 'time' in name:
npn = obj(0, 'D')
else:
npn = obj(0)
nat = npn.item()
print('{0} ({1!r}) -> {2}'.format(name, npn.dtype.char, type(nat)))
except:
pass
Istnieje kilka rodzajów NumPy, które nie mają odpowiednika natywną Pythona na niektórych systemach, w tym: clongdouble
, clongfloat
, complex192
, complex256
, float128
, longcomplex
, longdouble
i longfloat
. Przed użyciem należy je przekonwertować na ich najbliższy odpowiednik NumPy .item()
.
np.str
nie jest typem Numpy, tznnp.str is str
. Jest tylko aliasem do standardowego typu Python. To samo znp.float
,np.int
,np.bool
,np.complex
, inp.object
. Typy Numpy mają końcowe_
, npnp.str_
.np.float64(0).item()
i takżenp.float(0).item()
. Innymi słowy, w przypadkach, w których wiadomo, co robić, należy wspierać.item()
metodę, nawet jeśli po prostu zwraca tę samą wartość. W ten sposób mogłem aplikować.item()
na znacznie bardziej numpy skalarach bez specjalnej obudowy. W tej chwili pozornie równoległe koncepcje różnią się ze względu na implementację. Całkowicie rozumiem, dlaczego tak się stało. Ale to irytuje użytkownika biblioteki.odkryłem, że mam mieszany zestaw typów numpy i standardowego pytona. ponieważ wszystkie typy numpy pochodzą
numpy.generic
, oto jak możesz przekonwertować wszystko na standardowe typy python:źródło
np.asscalar()
metodę. Czemu? Prawdopodobnie bez wyraźnego powodu. Pomimo dekady względnej stabilności, NumPy API jest obecnie niestabilnym ruchomym celem, wymagającym stałej konserwacji od dalszych aplikacji. Przynajmniej zostawili namitem()
metodę ... na razie.if isinstance(o, numpy.generic): return o.item() raise TypeError
a ona ponownie staje się nieaktualną odpowiedzią: DJeśli chcesz przekonwertować (numpy.array LUB numpy skalar LUB typ rodzimy LUB numpy.darray) na typ rodzimy, możesz po prostu zrobić:
tolist skonwertuje twój skalar lub tablicę na rodzimy typ Pythona. Domyślna funkcja lambda zajmuje się przypadkiem, w którym wartość jest już natywna.
źródło
lambda: value
to, że nie chcemy żadnych danych wejściowych.getattr
+tolist
combo jest nie tylko uniwersalne, ale nawet wektoryzowane! (unlinke .item ())Co powiesz na:
źródło
np.dtype('mint8')
każdą dodatnią liczbę całkowitąm
. Nie może być wyczerpującego mapowania. (Nie wierzę też, że istnieje wbudowana funkcja do wykonania tej konwersji dla ciebie. Mogę się mylić, ale nie sądzę :))>>> print([numpy.asscalar(x) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.6499999999999999, 0.6, 0.55, 0.5, 0.44999999999999996, 0.3999999999999999, 0.35, 0.29999999999999993, 0.25, 0.19999999999999996, 0.1499999999999999, 0.09999999999999998, 0.04999999999999993, 0.0]
jak widać nie wszystkie wartości zostały poprawnie przekonwertowane.>>> print([numpy.asscalar(round(x,2)) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.0]
tolist()
jest bardziej ogólnym podejściem do osiągnięcia tego celu. Działa w każdym prymitywnym typie, a także w tablicach lub macierzach.W rzeczywistości nie daje listy, jeśli jest wywoływana z typów pierwotnych:
numpy == 1.15.2
źródło
Możesz także wywołać
item()
metodę obiektu, który chcesz przekonwertować:źródło
Myślę, że możesz po prostu napisać funkcję konwersji typu ogólnego tak:
Oznacza to, że nie ma ustalonych list, a Twój kod będzie skalowany wraz z większą liczbą typów.
źródło
numpy.ndarray
z 1 zerem przy użyciuzeros()
i wywołaniendarrays
tolist()
funkcji w celu konwersji na typy rodzime. Raz w rodzimych typach proszę o typ i zwrot go.tolist()
jest fucntion zndarray
grep -r 'tolist' numpy
. (wciąż w toku, numpy jest ogromny!)numpy przechowuje te informacje w mapowaniu
typeDict
, abyś mógł zrobić coś takiego:Jeśli chcesz rzeczywistych typów python zamiast ich nazw, możesz:
źródło
Przepraszam, że spóźniłem się częściowo, ale patrzyłem na problem z przejściem tylko
numpy.float64
na zwykły Pythonfloat
. Widziałem 3 sposoby na zrobienie tego:npValue.item()
npValue.astype(float)
float(npValue)
Oto odpowiednie czasy z IPython:
Wygląda na to,
float(npValue)
że wydaje się znacznie szybszy.źródło
Moje podejście jest nieco zdecydowane, ale wydaje się, że gra we wszystkich przypadkach:
Stosowanie:
źródło
Dodatkowa uwaga na temat skalarów tablicowych dla tych, którzy nie potrzebują automatycznej konwersji i znają typ numpy wartości:
Źródło
Dlatego w większości przypadków konwersja może nie być wcale potrzebna, a skalar macierzy można zastosować bezpośrednio. Efekt powinien być identyczny z użyciem skalara Pythona:
Ale jeśli z jakiegoś powodu konieczna jest jawna konwersja, najlepszym rozwiązaniem jest użycie odpowiedniej wbudowanej funkcji Pythona. Jak pokazano w drugiej odpowiedzi, jest również szybszy niż
item()
metoda skalarna tablicowa .źródło
Przetłumacz cały ndarray zamiast jednego obiektu danych jednostki:
Jednak obsługa dużych ramek danych zajmuje kilka minut. Szukam również bardziej wydajnego rozwiązania. Mam nadzieję na lepszą odpowiedź.
źródło