python常用函数和使用技巧日常总结(不定期更新)

时间:2022-12-07 00:07:09

感觉专门花费大量时间去精通一门语言是很困难的,因为许多高深的用法即使你当时学会了,也会因为很少使用导致你很快忘记。反倒是在平时的学习过程中遇到一些很棒的用法记录下来,以便以后使用倒很有帮助。所以打算专门用一篇博文记录我所遇到的python语言中如numpy、matplotlib等比较棒的库的函数用法和技巧。

  • numpy.flatnonzero()
    函数用法大概是这样的:
    输入一个矩阵,返回了其中非零元素的位置:

    >>> import numpy as np
    >>> a = np.array([1,5,0,0,1,2])
    >>> print np.flatnonzero(a)
    [0 1 4 5]

    这个函数比较简单,你以为它只能返回非元素的位置?那你就错了,比如上面的例子,返回1和2的位置:

    >>> print np.flatnonzero(a==1)
    [0 4]
    >>> print np.flatnonzero(a==2)
    [5]

    对于一个n维矩阵,这个函数返回的是将该矩阵按行拉成一列后,每个元素所在的位置的下标。

  • numpy.concatenate((a1, a2, …), axis=0, out=None)
    将矩阵a1,a2….按照某一维度进行拼接:

    >>> a = np.arange(0,12,1)
    >>> a = a.reshape((4,3))
    >>> print a
    [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]]
    >>> b = np.arange(0,-6,-1)
    >>> b = b.reshape((2,3))
    >>> print b
    [[ 0 -1 -2] [-3 -4 -5]]
    >>> c = np.concatenate((a,b),axis=0) #沿着第一个维度进行拼接
    >>> prnint c
    [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11] [ 0 -1 -2] [-3 -4 -5]]
    
    >>> b = np.arange(0,-8,-1)
    >>> b = b.reshape((4,2))
    >>> print b
    [[ 0 -1] [-2 -3] [-4 -5] [-6 -7]]
    >>> c = np.concatenate((a,b),axis=1)  #沿着第二个维度进行拼接
    >>> print c
    [[ 0 1 2 0 -1] [ 3 4 5 -2 -3] [ 6 7 8 -4 -5] [ 9 10 11 -6 -7]]

    技巧:因为矩阵的拼接需要满足维度匹配的要求,所以在如果我们在高维度矩阵拼接时,遵循下面准则,就能保证不出错:要沿着x维度进行拼接,保证除了该维度以外的其他所有维度的维数一致,拼接后的矩阵除了x维度变化以外,其他维度均保持不变。 举个列子:

    >>> a = np.arange(0,24,1)
    >>> a = a.reshape((4,3,2,1))
    >>> b = np.arange(0,-16,-1)
    >>> b = b.reshape((4,2,2,1))
    >>> c = np.concatenate((a,b),axis=1)   #如果我想沿着第二个维度进行拼接,则矩阵b的第1、3、4维的维数和a的对应维度维数一致
    >>> print c.shape
    (4, 5, 2, 1)       #拼接后的矩阵除了第2维变大,其它维度和a保持一致
  • numpy.random.choice(a, size=None, replace=True, p=None)
    可以从一个int数字或1维array里随机选取内容,并将选取结果放入n维array中返回。p是一个一维度列表,对于于a中每个元素被选中的概率。

    >>> a = np.arange(1,10,1)
    >>> print a
    [1 2 3 4 5 6 7 8 9]
    >>> print (np.random.choice(a,size=9,replace=True))    #replace代表是否有放回的随机选取,True表示有放回
    [8 4 1 3 8 8 3 3 7]
    >>> print (np.random.choice(a,size=9,replace=False))     #False表示无放回
    [2 4 7 8 5 3 1 9 6]
    >>> np.random.choice(a,size=10,replace=True,p=[0,0,0.1,0.1,0.2,0.1,0.3,0.1,0.1]) #指定对应元素被选中的概率,可以看到7的概率最大,所以出现的次数最多
    array([8, 6, 5, 5, 7, 3, 5, 7, 7, 5])
    
  • numpy.array_split(ary, indices_or_sections, axis=0)和numpy.split(ary, indices_or_sections, axis=0)
    这两个函数都可以将一个多为数组按照指定维度进行切分,ary是被切分的对象数组,indices_or_sections是指定被切分的份数或一个列表(见下面示例),axis为指定维度。这两个函数唯一的区别是,split只能划分为等分的子数组,而array_split可以划分为长度不等的子数组,其计算公式如下,l为数组被切分维度的长度,n为被切分份数,则它返l%n个长度为(l//n)+1的子数组,其余的(n-l%n)个子数组长度为l//n(//为取整符号):

    
    ##能等分的例子
    
    >>> x = np.arange(12)
    >>> np.split(x, 3)
    [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])]
    >>> np.array_split(x, 4)
    [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11])]
    
    #按给定列表进行指定等分划分,可以把列表中的元素看作是原数组中被切分的位置的下标
    
    >>> np.array_split(x, [2, 5, 9, 11])
    [array([0, 1]), array([2, 3, 4]), array([5, 6, 7, 8]), array([ 9, 10]), array([11])]
    >>> np.split(x, [2, 5, 9, 11])
    [array([0, 1]), array([2, 3, 4]), array([5, 6, 7, 8]), array([ 9, 10]), array([11])]
    
    #不能被等分的例子,可以看到数组长度为12,分成5分,不能保证每一份的元素个数相等,因此split函数会报错,而对于array_split则会通过前面的公式来指定每一个子数组的大小,首先12%5=2,因此前两个数组的大小为(12//5)+1=3,剩下的(5-12%5)= 3个数组大小为12//5=2,所以结果为[array([0, 1, 2]), array([3, 4, 5]), array([6, 7]), array([8, 9]), array([10, 11])]
    
    >>> x = np.arange(12)
    >>> np.split(x, 5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/forever/anaconda2/lib/python2.7/site-packages/numpy/lib/shape_base.py", line 541, in split
        'array split does not result in an equal division')
    ValueError: array split does not result in an equal division
    >>> np.array_split(x, 5)
    [array([0, 1, 2]), array([3, 4, 5]), array([6, 7]), array([8, 9]), array([10, 11])]
  • python中list和numpy数组,对于赋值操作(=)都是属于浅拷贝,即指向同一块内存地址

    >>> a = np.arange(10)
    >>> a
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> b = a
    >>> a[0] -= 10
    >>> a
    array([-10,   1,   2,   3,   4,   5,   6,   7,   8,   9])
    >>> b
    array([-10,   1,   2,   3,   4,   5,   6,   7,   8,   9])   #b也会被修改
    >>> a = list(np.arange(10))
    >>> a
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> b = a
    >>> a[0] -= 10
    >>> a
    [-10, 1, 2, 3, 4, 5, 6, 7, 8, 9]      #b也会改变
    >>> b
    [-10, 1, 2, 3, 4, 5, 6, 7, 8, 9]    
  • numpy.stack和numpy.hstack、numpy.vstack

  • python中numpy矩阵元素的访问
    这是我们经常用的操作,但是其实很多时候我们对其中的原理并不是特别清楚,比如:

    >>> a = np.arange(0,28)
    >>> a = a.reshape([4,7])
    >>> a
    array([[ 0,  1,  2,  3,  4,  5,  6],
     [ 7, 8, 9, 10, 11, 12, 13],
     [14, 15, 16, 17, 18, 19, 20],
     [21, 22, 23, 24, 25, 26, 27]])
    >>> a[1,2]
    9
    >>> a[1][2]
    9

    这两种方式都可以完成一样的操作,即访问数组中的元素,但是其实它们是不一样的,看下面的例子:

    >>> a[0:3, 1:3]
    array([[ 1, 2], [ 8, 9], [15, 16]])
    >>> a[0:3][1:3]
    array([[ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20]])

    可以看到,在这种情况下,前者其实是切片草组,也就是从原数组中不破坏其结构的从中抽取部分行与列(对于二维数组来说),而后者则是先返回a[0:3]即原数组的前三行,然后再从这三行形成的新数组中返回[1:3]行,因此返回的数组列的维度不变。

  • numpy.maximum(X, Y, out=None)
    将X和Y进行比较,并取最大者

>>> a
array([1, 2, 3, 4, 5, 6])
>>> b
array([2, 4, 5, 2, 1, 4])
>>> np.maximum(a,b)
array([2, 4, 5, 4, 5, 6])
>>> a = np.arange(0,28)
>>> a = a.reshape([4,7])
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27]])
>>> np.maximum(a,10)     #用到了python的广播机制
array([[10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27]])
  • numpy.zeros_like(a, dtype=None, order=’K’, subok=True)
    创建一个与给定数组维度一样的元素全是0的新数组,后面两个参数一般不使用。(order:可选参数,c代表与c语言类似,行优先;F代表列优先)

    >>> x = np.arange(6)
    >>> x = x.reshape((2, 3))
    >>> x
    array([[0, 1, 2], [3, 4, 5]])
    >>> np.zeros_like(x)
    array([[0, 0, 0], [0, 0, 0]])
    >>> y = np.arange(3, dtype=float)
    >>> y
    array([ 0.,  1.,  2.])
    >>> np.zeros_like(y)
    array([ 0.,  0.,  0.])
  • numpy.prod(a, axis=None, dtype=None, out=None, keepdims=bool)
    对一个多维数组,返回指定维度上元素的乘积,示例:

    >>> a = np.arange(1, 29) / 100.
    >>> a
    array([ 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1 , 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2 , 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28]) >>> a = a.reshape((4,7)) >>> np.prod(a, axis = 0) array([ 2.64000000e-05, 6.62400000e-05, 1.22400000e-04, 1.98000000e-04, 2.96400000e-04, 4.21200000e-04, 5.76240000e-04]) >>> np.prod(a, axis = 1) array([ 5.04000000e-11, 1.72972800e-07, 5.86051200e-06, 5.96756160e-05]) >>> np.prod(a, axis = (0, 1)) 3.0488834461171415e-27 >>> np.prod(a) 3.0488834461171415e-27