我正在计算NN的成本函数。我从numpy.dot得到的(1,1)答案上做了一个numpy.squeeze。然后我得到一个形状的ndarray(0,1)。
什么是形状的ndarray()和形状(1,)的ndarray与形状(5)的形状有什么不同?
答案 0 :(得分:3)
(1, 1)
的ndarray类似于[[3]]
,就像1x1矩阵一样。(1,)
的ndarray类似于[3]
,就像大小为1的向量一样。()
的ndarray,a.k.a标量,类似于3
。差异是微妙的,因为由于广播规则标量和数组通常可以毫无问题地组合,但是您不能索引标量,而您可以索引大小为1的向量或大小为1x1的矩阵。另一方面,标量通常可以像原始Python值一样使用,例如int
或float
。如果您不想使用标量,则可以将axis
参数传递给np.squeeze
,以确保某些维度不被挤压,或使用np.atleast_1d
确保您传递的任何内容至少有一个维度。您还可以使用np.isscalar
检查某些内容是否为标量。
答案 1 :(得分:2)
dot
产生一个(1,1)数组:
In [1221]: x = np.ones((3,1))
In [1222]: xx = np.dot(x.T,x)
In [1223]: xx.shape
Out[1223]: (1, 1)
In [1224]: xx
Out[1224]: array([[ 3.]])
item
可用于从数组中提取该值:
Out[1227]: 3.0
In [1228]: type(_)
Out[1228]: float
您也可以通过索引选择项目,但type
会有所不同:
In [1229]: xx[0,0]
Out[1229]: 3.0
In [1230]: type(_)
Out[1230]: numpy.float64
出于多种目的,float
和np.float64
之间的区别并不重要。
squeeze
删除所有1号尺寸。在这种情况下,结果是0d数组。 item
仍有效。索引也可以使用正确的索引大小(即长度为0的元组):
In [1231]: xx0 = np.squeeze(xx)
In [1232]: xx0.shape
Out[1232]: ()
In [1233]: xx0.item()
Out[1233]: 3.0
In [1234]: xx0[()]
Out[1234]: 3.0
In [1235]: type(_)
Out[1235]: numpy.float64
np.float64
的类继承是:
In [1236]: _.__mro__
Out[1236]:
(numpy.float64,
numpy.floating,
numpy.inexact,
numpy.number,
numpy.generic,
float,
object)
所以isinstance
float仍将返回true
In [1237]: isinstance(xx0.item(),float)
Out[1237]: True
In [1238]: isinstance(xx0[()],float)
Out[1238]: True
In [1239]: isinstance(xx[0,0],float)
Out[1239]: True
我不会依赖于所有numpy dtypes。