mayaview 发表于 2014-2-18 00:10

Numpy中ndarray的处理函数(一):take()函数

本帖最后由 Rainyboy 于 2014-2-17 20:59 编辑

Numpy对于用Python做科学计算的人基本是必须的函数库之一,其中主要提供了ndarray和ufunc两个强大的数据类型。但是作为免费软件,往往Numpy不能自动的调用最优化的函数执行操作,所以用户必须自己对Numpy的函数有所了解。我从文档里挑了几个ndarray的函数,还算比较容易理解,太抽象的函数对于初次接触的人可能难度较大。今天先介绍ndarray的take函数,为什么要用take的原因在文章最后。
第一个函数ndarray的take函数,文档如下:


take(a, indices, axis=None, out=None, mode='raise')
Take elements from an array along an axis.

This function does the same thing as "fancy" indexing (indexing arrays
using arrays); however, it can be easier to use if you need elements
along a given axis.

Parameters
----------
a : array_like
    The source array.
indices : array_like
    The indices of the values to extract.

    .. versionadded:: 1.8.0

    Also allow scalars for indices.
axis : int, optional
    The axis over which to select values. By default, the flattened
    input array is used.



其他参数暂时不用关心。这个函数的功能是按照某个轴提取ndarray中的元素,默认是在一维索引的数组中提取(不知道是什么的话,可以看flatten函数,或者直接不管)。我们经常用到的是取某个函数的行或者列,这个时候设置的axis分别是0和1(这点一定要注意,take函数的axis不是along the axis,而是slecte the axis,这和其他函数基本是反着的)。

举个例子(我默认from numpy import *,免得敲太多np.了):

a=arange(6).reshape(3,2)

这样a就是(用Fortran的注意了,Numpy默认是C的数组顺序)
array([,
       ,
       ])

然后 take(a,,axis=0) 也就是按行提取a的第一行2次,第二行2次:
array([,
       ,
       ,
       ])


注意到index里的数字是可以重复的,怎么用就看你了,很多很高效的程序频繁的使用这个技术。

然后就得回到为什么要用take了。其实原因很简单,快而且直观。
a=random.random((1000,2000))
b=randint(0,1000,100)

%timeit take(a,b,axis=0)
1000 loops, best of 3: 193 μs per loop

%timeit take(a,b,axis=1)
1000 loops, best of 3: 1.47 ms per loop


%timeit a
100 loops, best of 3: 2.53 ms per loop


%timeit a[:,b]
100 loops, best of 3: 4.02 ms per loop


可以看到take按行提取时换到不行了,比index快了一个多数量级,即便是按列也快了一倍多。所以,如果你要提取整行或者整列提取ndarray里的数,不要忘了用take。结果是一样的哦!

In : array_equal(take(a,b,axis=0),a)
Out: True

In : array_equal(take(a,b,axis=1),a[:,b])
Out: True



Rainyboy 发表于 2014-2-18 04:00

很好的例子,期待你的系列!
页: [1]
查看完整版本: Numpy中ndarray的处理函数(一):take()函数