On Tue, Dec 28, 2021 at 10:19 AM Chris Angelico <ros...@gmail.com> wrote:

> I'm not sure about that.
>
> >>> numpy.log(2.71828)
> 0.999999327347282
> >>> numpy.log([2.71828])
> array([0.99999933])
> >>> type(numpy.log(2.71828))
> <class 'numpy.float64'>
> >>> type(numpy.log([2.71828]))
> <class 'numpy.ndarray'>
>

well, yes, there is a odd wart in numpy that there are zero-dimensional
arrays, and there are scalars, which almost, but not quite the same:


In [81]: arr = np.array(3.0)

In [82]: arr.shape
Out[82]: ()

In [83]: scalar = np.float64(3.0)

In [84]: scalar.shape
Out[84]: ()

In [85]: len(arr)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-85-23f199ad2330> in <module>
----> 1 len(arr)

TypeError: len() of unsized object

In [86]: len(scalar)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-86-d68a51ddf681> in <module>
----> 1 len(scalar)

TypeError: object of type 'numpy.float64' has no len()

In [87]: 5.0 * arr
Out[87]: 15.0

In [88]: 5.0 * scalar
Out[88]: 15.0

But they are almost interchangeable -- the reason the distinction is there
at all is for some internal numpy structural / legacy reasons.

I think it boils down to numpy scalars being more-or-less interchangable
with the built in python number types

(https://numpy.org/neps/nep-0027-zero-rank-arrarys.html)

Note that if you index into an ndarray, you get one less dimension, until
you get to zero dimensions, which is a scalar.

In [98]: arr2 = np.ones((3,4))

In [99]: arr2.shape
Out[99]: (3, 4)

In [100]: arr1 = arr2[0]

In [101]: arr1.shape
Out[101]: (4,)

In [102]: arr0 = arr1[0]

In [103]: arr0.shape
Out[103]: ()

In [104]: arr0[0]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-104-29631edfe735> in <module>
----> 1 arr0[0]

IndexError: invalid index to scalar variable.

Anyway, the point is that the distinction between scalar and array is the
same as between 1D array and 2D array, and that individual functions and
operators don't need to be different for operating on different dimensions
of arrays.

Not sure how significant that is, but it does still distinguish between
> values and arrays.


While numpy is strictly making a distinction between the *type* of scalar
values and arrays, it isn't making a distinction in the *concept* of a
scalar value.

In the context of this thread, I think the relevant point is that
"array-oriented" operations are another syntactical way of expressing
operations on collections of data, as opposed to various ways to spell
loopsing, which is what map() and comprehensions are.

-CHB

-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/IXS2KTIRZEAHORUMSFUFK2SUGE2SPD7F/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to