Python库Numpy的argpartition函数浅析

最近在研究用Python实现K邻近算法的KD树,发现一个奇怪的现象,就是为什么没有在网上搜到关于numpy的argpartition的任何中文的文章。难道是我搜索方法有问题吗?所以自己写一篇简单的文章说说这个有意思的函数。
这个函数有什么用呢?我举几个例子,您可能就明白她的作用了。
例子一:找到数组的最大最小值,虽然这不是很合适,牛刀小用了。

>>> import numpy as np
>>> arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])
>>> np.argpartition(arr, len(arr)-1)
array([5, 3, 2, 6, 4, 0, 1, 7], dtype=int32)
>>> arr[np.argpartition(arr, len(arr)-1)[len(arr)-1]]
120
>>> arr[np.argpartition(arr, 0)[0]]
0

例子二:找到数组的第3小(index=2)的值和第2大(index=-2)的值。这次就很合适了。

>>> arr[np.argpartition(arr, 2)[2]]
10
>>> arr[np.argpartition(arr, -2)[-2]]
57

例子三:同时找到第3和第4小的值。注意这里,用[2,3]同时将第3和第4小的排序好,然后可以分别通过下标[2]和[3]取得。

>>> arr[np.argpartition(arr, [2,3])[2]]
10
>>> arr[np.argpartition(arr, [2,3])[3]]
23

有朋友您可能会问了,我直接把数组arr排序一次不就行了吗?还需要argpartition做什么?这是个好问题。其实我开始也有这样的疑问,然后我做了一个实验,立刻明白了这样做的好处。

如果您也感兴趣,不妨听我再多说几句。这个实验是这样的。

我生成了一个数组,为了达到更好的效果,这个数组被设计成倒序,这样sort会得到最坏的结果。

>>> arr = np.array([8,7,6,5,4,3,2,1])
>>> np.argpartition(arr, 0)
array([7, 1, 2, 3, 4, 5, 6, 0], dtype=int32)
>>> np.argpartition(arr, 1)
array([7, 6, 2, 3, 4, 5, 1, 0], dtype=int32)
>>> np.argpartition(arr, 2)
array([7, 6, 5, 3, 4, 2, 1, 0], dtype=int32)
>>> np.argpartition(arr, 3)
array([6, 7, 5, 4, 3, 1, 2, 0], dtype=int32)
>>> np.argpartition(arr, 4)
array([4, 7, 6, 5, 3, 1, 2, 0], dtype=int32)
>>> np.argpartition(arr, 5)
array([4, 7, 6, 5, 3, 2, 1, 0], dtype=int32)
>>> np.argpartition(arr, 6)
array([4, 7, 6, 5, 3, 2, 1, 0], dtype=int32)
>>> np.argpartition(arr, 7)
array([4, 7, 6, 5, 3, 2, 1, 0], dtype=int32)

第一次调用,给第二个参数传了0,说明我需要返回最小值得索引index。得到的返回值是array([7, 1, 2, 3, 4, 5, 6, 0], dtype=int32),在这个返回的array中,我关心的是第0个值(7),它是原数组arr的索引,arr[7]就是我要找的最小值。请注意返回值中的其他几个索引值,和原数组的索引比起来,他们基本上没有什么变化。接下来的几次调用也是这种情况,其实这也就说明argpartition没有对他不关心的数据做太大的改动或者操作。

argpartition只排序第2个参数指定的位置,其他的位置的值不保证排序正确。因为这样只调用一次argpartition函数,也就是执行了一遍搜索就找到了n个值的排位,所以argpartition的效率比较高(别激动,我猜的)。据说是O(n)。

下面是函数的英文帮助,我在KD树的代码里只用到了前2个参数,而且只对一维数组排序,够了。使用不同的参数可以对复杂数据处理,我没有用到,也没有去实验,以后用到了我会补充的。
我写的KD树代码:http://blog.csdn.net/weixin_37722024/article/details/62226957

numpy.argpartition
numpy.argpartition(a, kth, axis=-1, kind=’introselect’, order=None)[source]
Perform an indirect partition along the given axis using the algorithm specified by the kind keyword. It returns an array of indices of the same shape as a that index data along the given axis in partitioned order.

New in version 1.8.0.

Parameters:
a : array_like
Array to sort.
kth : int or sequence of ints
Element index to partition by. The k-th element will be in its final sorted position and all smaller elements will be moved before it and all larger elements behind it. The order all elements in the partitions is undefined. If provided with a sequence of k-th it will partition all of them into their sorted position at once.
axis : int or None, optional
Axis along which to sort. The default is -1 (the last axis). If None, the flattened array is used.
kind : {‘introselect’}, optional
Selection algorithm. Default is ‘introselect’
order : str or list of str, optional
When a is an array with fields defined, this argument specifies which fields to compare first, second, etc. A single field can be specified as a string, and not all fields need be specified, but unspecified fields will still be used, in the order in which they come up in the dtype, to break ties.
Returns:
index_array : ndarray, int
Array of indices that partition a along the specified axis. In other words, a[index_array] yields a partitioned a.
See also
partition
Describes partition algorithms used.
ndarray.partition
Inplace partition.
argsort
Full indirect sort
Notes

See partition for notes on the different selection algorithms.

Examples

One dimensional array:

>

x = np.array([3, 4, 2, 1])
x[np.argpartition(x, 3)]
array([2, 1, 3, 4])
x[np.argpartition(x, (1, 3))]
array([1, 2, 3, 4])

x = [3, 4, 2, 1]
np.array(x)[np.argpartition(x, 3)]
array([2, 1, 3, 4])

  • 22
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Python中的NumPy库是一个非常有用的科学计算库,它提供了许多常用函数用于处理数组和矩阵。以下是一些Python中NumPy常用函数的介绍: 1. numpy.array():创建一个NumPy数组。可以传入一个列表或者元组作为参数,返回一个NumPy数组对象。 2. numpy.arange():创建一个具有指定范围和步长的数组。可以设置起始值、结束值和步长,返回一个包含这个范围内所有值的NumPy数组。 3. numpy.zeros():创建一个指定大小的全0数组。可以传入一个表示数组形状的元组或者整数作为参数,返回一个全0的NumPy数组。 4. numpy.ones():创建一个指定大小的全1数组。与numpy.zeros()类似,可以传入一个表示数组形状的元组或者整数作为参数,返回一个全1的NumPy数组。 5. numpy.linspace():在指定的范围内创建均匀间隔的数组。可以设置起始值、结束值和数组长度,返回一个包含指定范围内均匀间隔的元素的NumPy数组。 6. numpy.random.rand():生成指定形状的随机数数组。可以传入一个表示数组形状的元组或者整数作为参数,返回一个包含指定形状的随机数的NumPy数组。 7. numpy.max():返回数组中的最大值。可以传入一个NumPy数组作为参数,返回数组中的最大值。 8. numpy.min():返回数组中的最小值。可以传入一个NumPy数组作为参数,返回数组中的最小值。 9. numpy.mean():计算数组的平均值。可以传入一个NumPy数组作为参数,返回数组的平均值。 10. numpy.sum():计算数组中所有元素的和。可以传入一个NumPy数组作为参数,返回数组中所有元素的和。 11. numpy.reshape():改变数组的形状。可以传入一个表示新形状的元组作为参数,返回一个具有新形状的NumPy数组。 这些只是Python中NumPy库中常用函数的一部分,还有许多其他有用的函数可以用于数组和矩阵的操作。希望这些函数能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值