最近在看SVM程序时遇到了nonzero()函数,对其的返回值开始有误解,因此记录下来.np.nonzero函数是numpy中用于得到数组array中非零元素的位置(数组索引)的函数.
np.nonzero()
nonzero(a)
返回数组a中非零元素的索引值数组。
(1)只有a中非零元素才会有索引值,那些零值元素没有索引值;
(2)返回的索引值数组是一个2维tuple数组,该tuple数组中包含一维的array数组。其中,一维array向量的个数与a的维数是一致的。
(3)索引值数组的每一个array均是从一个维度上来描述其索引值。比如,如果a是一个二维数组,则索引值数组有两个array,第一个array从行维度来描述索引值;第二个array从列维度来描述索引值。
(4) 该np.transpose(np.nonzero(x))
函数能够描述出每一个非零元素在不同维度的索引值。
(5)通过a[nonzero(a)]得到所有a中的非零值
从代码来看:
import numpy as np
a=[1,0,2]
b=np.nonzero(a)
print(b)
则输出如下:
array([0,2]),即a[0],a[2]是非零
一维数组很好理解,那么二维呢
import numpy as np
a=[[0],[1],[2]]
b=np.nonzero(a)
print(b)
输出如下:
(array([1, 2]), array([0, 0]))
这里我们可以看出,实际上逻辑上理解的应该是([1,0],[2,0]),也就是第一个array存储的是行号,第二个存储的是列号
这种方式在SVM对应的代码是:
vaildEcacheList = nonzero(oS.eCache[:,0].A)[0]
得到我想要的非零的向量的行号
,三维数组也是一样:
a = np.array([[[0,1],[1,0]],[[0,1],[1,0]],[[0,0],[1,0]]])
b = np.nonzero(a)
print(np.array(b).ndim)
print(b)
结果:
2
(array([0, 0, 1, 1, 2], dtype=int64), array([0, 1, 0, 1, 1], dtype=int64), array([1, 0, 1, 0, 0], dtype=int64))
说明:由于a是3维数组,因此,索引值数组有3个一维数组。
print(a)
[[[0 1]
[1 0]]
[[0 1]
[1 0]]
[[0 0]
[1 0]]]