Dlaczego tablice 0d w Numpy nie są uważane za skalarne?

Z pewnością tablica 0d jest skalarna, ale Numpy nie wydaje się tak myśleć... czy coś przeoczyłem, czy tylko źle zrozumiałem ten pomysł?

>>> foo = numpy.array(1.11111111111, numpy.float64)
>>> numpy.ndim(foo)
0
>>> numpy.isscalar(foo)
False
>>> foo.item()
1.11111111111
Author: Dan Lew, 2009-04-21

2 answers

Nie należy się nad tym zbytnio zastanawiać. Ostatecznie jest to lepsze dla zdrowia psychicznego i długowieczności jednostki.

Dziwna sytuacja z Numpy skalarnymi typami została rozwinięta z faktu, że nie ma wdzięcznego i spójnego sposobu na degradację macierzy 1x1 do typów skalarnych. Chociaż matematycznie są one tym samym, są obsługiwane przez bardzo inny kod.

Jeśli robisz jakąś ilość kodu naukowego, ostatecznie chcesz, aby takie rzeczy jak max(a) działały na macierzach wszystkich rozmiarów, nawet skalarów. Matematycznie jest to zupełnie rozsądna rzecz, której można się spodziewać. Jednak dla programistów oznacza to, że cokolwiek prezentuje Skalary w Numpy powinno mieć .kształt i .ndim attirbute, więc przynajmniej ufuncs nie muszą dokonywać jawnego sprawdzania typu na jego wejściu dla 21 możliwych typów skalarnych w Numpy.

Z drugiej strony, powinny one również pracować z istniejącymi bibliotekami Pythona, które wykonuje jawne sprawdzanie typu na typie skalarnym. To jest dylemat, ponieważ Numpy ndarray muszą indywidualnie zmienić swój typ, gdy zostały one zredukowane do skalara, i nie ma sposobu, aby dowiedzieć się, czy to miało miejsce bez konieczności sprawdzania całego dostępu. W rzeczywistości przejście tej trasy prawdopodobnie sprawiłoby, że praca z nią byłaby śmiesznie powolna według standardów typu skalarnego.

Rozwiązaniem programisty Numpy jest dziedziczenie skalarów Ndarray i Python dla własnego typu skalarnego, tak aby wszystkie Skalary również miały .kształt, .ndim,T, itd itd. 1x1 macierz nadal tam będzie, ale jej użycie będzie zniechęcające, jeśli wiesz, że będziesz miał do czynienia ze skalarem. Chociaż teoretycznie powinno to działać dobrze, czasami nadal można było zobaczyć niektóre miejsca, w których brakowało wałka malarskiego, a brzydkie wnętrzności są narażone dla wszystkich, aby zobaczyć: {]}

>>> from numpy import *
>>> a = array(1)
>>> b = int_(1)
>>> a.ndim
0
>>> b.ndim
0
>>> a[...]
array(1)
>>> a[()]
1
>>> b[...]
array(1)
>>> b[()]
1

Naprawdę nie ma powodu, dla którego a[...] i a[()] powinny zwracać różne rzeczy, ale tak jest. Są propozycje zmian, ale wygląda na to, że zapomnieli dokończyć zadanie za 1x1 tablice.

Potencjalnie większym i być może niemożliwym do rozwiązania problemem jest fakt, że Skalary Numpy są niezmienne. Dlatego "rozpylanie" skalara do ndarray, matematycznie operacja adjoint zwijania tablicy do skalara, jest PITA do zaimplementowania. Nie można wyhodować skalara Numpy, nie można go z definicji wrzucić do ndarray, mimo że newaxis w tajemniczy sposób działa na nim:

>>> b[0,1,2,3] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'numpy.int32' object does not support item assignment
>>> b[newaxis]
array([1])

W Matlab, wzrost wielkości skalara jest całkowicie akceptowalny i bezmózgowy operacja. W Numpy musisz trzymać a = array(a) wszędzie gdzie myślisz będziesz miał możliwość zaczynania od skalara, a kończenia na tablicy. Rozumiem, dlaczego Numpy musi być w ten sposób, aby grać ładnie z Pythonem, ale to nie zmienia faktu, że wiele nowych przełączników jest głęboko zdezorientowanych. Niektórzy mają wyraźną pamięć o zmaganiu się z tym zachowaniem i ostatecznie wytrwałości, podczas gdy inni, którzy są zbyt daleko, zazwyczaj pozostają z jakimś głębokim, bezkształtnym umysłem blizna, która często nawiedza ich najbardziej niewinne sny. To brzydka sytuacja dla wszystkich.

 143
Author: Tim Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-28 23:19:46

Musisz stworzyć tablicę skalarną trochę inaczej:

>>> x = numpy.float64(1.111)
>>> x
1.111
>>> numpy.isscalar(x)
True
>>> numpy.ndim(x)
0

Wygląda na to, że Skalary w numpy mogą być nieco odmiennym pojęciem od tego, do czego można się przyzwyczaić z czysto matematycznego punktu widzenia. Zgaduję, że myślisz w kategoriach skalarnych matur?

 6
Author: Jason Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-21 15:20:27