再说numpy.nonzero()函数

像nonzero()这种比较常用的函数,在百度一搜就有一大把的解释和使用方法,但是喵哥却被网上丰富的资源搞晕了,后来经过喵哥一步一步的调试,总算看清了nonzero()的真实面目。为了以后可以再来看看,也为后来者不再被网上的解释搞糊涂,喵哥特地在此再说numpy.nonzero()函数。

事情的起始是这样的,喵哥在理解别人写的K-means时,遇到这么一句代码:

ptsInClust = dataSet[np.nonzero(clusterAssment[:,0].A == cent)[0]]

这句代码就用到了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中的非零值

总结的前三条把nonzero()的基本用法给说明白了,但是这种的使用方法并不可以完美的解释喵哥遇到的问题。

nonzero(clusterAssment[:,0].A == cent)里面的不是一个数组,而是一个表达式,表达式应该是与真假有关,为了进一步了解nonzero(),使用了help,发现还真有相关的描述:

A common use for ``nonzero`` is to find the indices of an array, where a condition is True.

那么,nonzero(a)的用法总结应该改一下:只有a为真值的元素才会有索引值。其余的说明是OK的。所以,

ptsInClust = dataSet[np.nonzero(clusterAssment[:,0].A == cent)[0]]

要表达的意思是:把clusterAssment[:,0].A中与cent(在代码中表示簇)一样的元素索引提取出来,又有nonzero()返回值是一个tuple,nonzero()[0]表示的是保证表达式为真值的元素位置的行坐标,然后利用这个行坐标提取出dataset对应的元素。

这样的解释也跟K-means的原理相符合:在聚类不满足介质条件时,还得求出每个簇的中心作为新的质心。

例子:

import numpy
#1.nonzero(python的简单序列对象)

a = [1,0,0,5,6,1,0,1]
b = numpy.nonzero(a)
print(b)

'''
输出:(array([0, 3, 4, 5, 7], dtype=int64),),其实就是一个包含一个array的tuple,如果取
b[0][1],会得到3.

'''

c = [[1,2,0],[5,0,1]]
d = numpy.nonzero(c)
print(d)
'''
输出:(array([0, 0, 1, 1], dtype=int64), array([0, 1, 0, 2], dtype=int64)),array([0, 0, 1, 1], dtype=int64)表示的是行坐标,array([0, 1, 0, 2], dtype=int64)表示的是列坐标
'''

#2.nonzero(python的表达式)
a = numpy.array([1,0,0,5,6,1,0,1])
b = numpy.nonzero(a > 1)
print(b)
'''
输出:(array([3, 4], dtype=int64),)
'''

c = numpy.array([[1,2,0],[5,0,1]])
d = numpy.nonzero(c == 1)
print(d)
'''
输出:(array([0, 1], dtype=int64), array([0, 2], dtype=int64))
'''

 

 

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值