为什么Numpy中的0d数组不被认为是标量?

Sal*_*ley 63 python numpy

肯定是一个0d阵列是标量,但Numpy似乎并不这么认为......我错过了什么或者我只是误解了这个概念?

>>> foo = numpy.array(1.11111111111, numpy.float64)
>>> numpy.ndim(foo)
0
>>> numpy.isscalar(foo)
False
>>> foo.item()
1.11111111111
Run Code Online (Sandbox Code Playgroud)

Tim*_*Lin 129

人们不应该考虑太多.它最终会改善个人的心理健康和长寿.

Numpy标量类型的奇怪情况是由于没有优雅和一致的方法将1x1矩阵降级为标量类型.尽管在数学上它们是相同的,但它们由非常不同的代码处理.

如果你一直在做任何数量的科学代码,最终你会想要max(a)处理各种规模的矩阵,甚至是标量.在数学上,这是一个非常明智的预期.但是对于程序员来说,这意味着Numpy中的任何提示标量都应该具有.shape和.ndim attirbute,所以至少ufuncs不必对Numpy中21种可能的标量类型的输入进行显式类型检查.

在另一方面,他们也应该与现有的Python库的工作确实做的标量型显式的类型检查.这是一个两难的问题,因为Numpy ndarray在被缩减为标量时必须单独改变它的类型,并且如果没有对所有访问进行检查,就无法知道是否已经发生了这种情况.实际上走这条路线可能会使标量类型标准的工作变得有点可笑.

Numpy开发人员的解决方案是从ndarray和Python标量继承其自己的scalary类型,所以所有标量也有.shape,.ndim,.T等等.1x1矩阵仍将存在,但它的用途将是如果你知道你将要处理一个标量,那就气馁了.虽然这在理论上应该可以正常工作,偶尔你仍然可以看到他们错过了油漆滚筒的一些地方,丑陋的内脏暴露给所有人看到:

>>> 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
Run Code Online (Sandbox Code Playgroud)

真的没有理由a[...]a[()]应该返回不同的东西,但它确实如此.有一些建议可以改变这一点,但看起来他们忘了完成1x1阵列的工作.

一个潜在的更大,可能是不可解决的问题是,Numpy标量是不可变的.因此,将标量"喷射"到ndarray中,数学上将阵列折叠成标量的伴随操作是PITA实现的.你实际上不能生成一个Numpy标量,它根本无法被投射到一个ndarray中,即使newaxis神秘地使用它:

>>> 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])
Run Code Online (Sandbox Code Playgroud)

在Matlab中,增加标量的大小是一种完全可以接受的无脑操作.在Numpy中,你必须在a = array(a)任何地方坚持使用jarring ,你认为你有可能从一个标量开始并最终得到一个数组.我理解为什么Numpy必须以这种方式与Python玩得很好,但这并没有改变许多新的切换器对此深感困惑的事实.有些人有明显的记忆力来挣扎于这种行为,并最终坚持不懈,而其他太远的人通常会留下一些深深无形的精神疤痕,经常困扰着他们最无辜的梦想.对所有人来说这是一个丑陋的情况.

  • +1哲学介绍:-) (28认同)
  • 你考虑过写作方面的职业吗? (6认同)
  • 很多这似乎是matlab看待事物的方式 - "你实际上不能成长Numpy标量"_ - 你也不能成长np.array.明确大小会使偶然的O(N ^ 2)行为变得更难._"根据定义,它不能被转换为ndarray"_ - 这就是`np.asarray(标量)`的作用._"1x1矩阵..."_ - 将事物视为固有的2D或矩阵,这对此无益 (5认同)

Jas*_*ker 6

您必须以不同的方式创建标量数组:

>>> x = numpy.float64(1.111)
>>> x
1.111
>>> numpy.isscalar(x)
True
>>> numpy.ndim(x)
0
Run Code Online (Sandbox Code Playgroud)

看起来像numpy中的标量可能与您从纯粹的数学角度习惯的概念有点不同.我猜你在考虑标量基质方面?