为什么在Numpy的0D数组不考虑标量?

当然0D数组是标量,但Numpy似乎并不这么认为…我错过了什么,或者我只是误解了这个概念?

>>> foo = numpy.array(1.11111111111, numpy.float64) >>> numpy.ndim(foo) 0 >>> numpy.isscalar(foo) False >>> foo.item() 1.11111111111 

人们不应该太想它。 个人的精神健康和长寿最终会更好。

Numpy标量types的好奇情况是由于没有优雅和一致的方法将1x1matrix降级为标量types而造成的。 即使在math上它们是相同的东西,它们是由非常不同的代码处理的。

如果你已经做了大量的科学代码,最终你会希望像max(a)这样的东西在各种规模的matrix上工作,甚至是标量。 在math上,这是一个非常明智的事情期望。 然而,对于程序员来说,这意味着无论Numpy中的所有呈现标量都应该具有.shape和.ndim属性,所以至lessufuncs不必对Numpy中的21种可能的标量types的input进行显式types检查。

另一方面,他们还应该使用现有的Python库,对标量types进行显式的types检查。 这是一个两难的问题,因为一个Numpy ndarray在沦为标量的时候不得不单独改变它的types,而且如果没有对所有访问进行检查,就无法知道它是否发生了。 实际上,通过标量types的标准来做这个工作可能会慢一些。

Numpy开发人员的解决scheme是从它们自己的scalarytypesinheritancendarray和Python标量,所有标量也都有.shape,.ndim,.T等等.1x1matrix仍然存在,但是它的使用将会是如果你知道你会处理一个标量,那就不要灰心了。 虽然这在理论上应该是正常的,但偶尔你仍然可以看到一些他们错过了油漆滚筒的地方,丑陋的内脏暴露在众人面前:

 >>> 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 

a[...]a[()]应该返回不同的东西是没有道理的,但是确实如此。 有build议,以改变这一点,但看起来他们忘了完成1x1arrays的工作。

一个可能更大,也可能是不可解决的问题是,Numpy标量是不可改变的。 因此,将标量“喷”到ndarray中,math上将数组折叠成标量的伴随操作是PITA实现的。 你不可能真正生长一个Numpy标量,它不能被定义为一个ndarray,尽pipenewaxis神秘的工作:

 >>> 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]) 

在Matlab中,增加标量的大小是一个完全可以接受的和无脑的操作。 在Numpy中,你必须在所有你认为可以用一个标量开始并以一个数组结尾的地方粘住a = array(a) 。 我明白为什么Numpy必须以这种方式与Python打好关系,但这并没有改变很多新的切换器对此深感困惑的事实。 有些人明确表示要为这种行为而奋斗,并最终坚持不懈,而另外一些过于遥远的人通常会留下一些深深的无形的精神疤痕,而这些精神疤痕常常困扰着他们最无辜的梦想。 这是一个丑陋的情况。

你必须以不同的方式创build标量数组:

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

看起来像numpy中的标量可能与纯粹的math观点可能会有些不同。 我猜你正在考虑用标量符号吗?