Numpy常见操作

数组的创建

  • 创建数组

    1
    np.array([1,2,3])
  • 创建指定步长的数组

    1
    2
    # 从0开始创建100个 step为10
    np.arange(0, 100, 10)
  • 创建一个指定范围区间的数组,其中的元素呈线性分布

    1
    2
    # 范围介于[0,2π] 共包含50个元素
    np.linspace(0, 2 * np.pi, 50)
  • 创建全为1的数组

    1
    np.ones((2,3,4), dtype=np.int16)
  • 创建全为0的数组

    1
    np.zeros((3,4))
  • 创建随机数组,大小取决于存储器状态

    1
    np.empty((2,3))
  • 创建随机数组(浮点数)

    1
    np.random.random((2,3))
  • 创建随机数组(整数)

    1
    np.random.randint(0,10,5)
  • 创建一个指定区间的随机数组

    1
    np.random.uniform(-10,+10,10) # 创建大于-10小于10的10个元素的数组
  • 以e为底的指数函数

    1
    np.exp((2,3))
  • 创建单位矩阵

    1
    2
    3
    4
    5
    >>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I"
    >>> u
    array([[ 1., 0.],
    [ 0., 1.]])
    >>> j = np.array([[0.0, -1.0], [1.0, 0.0]])

数组的操作

  • 更改形状

    1
    2
    3
    a = np.arange(25)
    # 将a变形为5x5
    a.reshape(5,5)
  • 更改形状,自动计算剩所在维度的长度

    1
    2
    3
    a = np.arange(25)
    # 将维度指定为-1将会自动计算
    a.reshape(5,-1)
  • 获取展开的数组

    1
    a.ravel()
  • 将两个数组堆叠起来

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 先创建两个数组

    >>> a = np.floor(10*np.random.random((2,2)))
    >>> a
    array([[ 8., 8.],
    [ 0., 0.]])
    >>> b = np.floor(10*np.random.random((2,2)))
    >>> b
    array([[ 1., 8.],
    [ 0., 4.]])
- 竖直方向堆叠

    
1
2
3
4
5
>>> np.vstack((a,b))
array([[ 8., 8.],
[ 0., 0.],
[ 1., 8.],
[ 0., 4.]])
- 水平方向堆叠起来
1
2
3
>>> np.hstack((a,b))
array([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])
  • r_和c_

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    a = np.array([[1, 2, 3],[7,8,9]])
    b = np.array([[4, 5, 6],[1,2,3]])

    np.c_[a,b]
    >>> array([[1, 2, 3, 4, 5, 6],
    [7, 8, 9, 1, 2, 3]])

    np.r_[a,b]
    >>> array([[1, 2, 3],
    [7, 8, 9],
    [4, 5, 6],
    [1, 2, 3]])
- r_ 和 c_ 可用于通过沿一个轴叠加数字来创建数组。它们允许使用范围字面量(“:”)

    
1
2
>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])
  • hsplit沿着水平方向拆分数组,vsplit沿着竖直方向拆分数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> a = np.floor(10*np.random.random((2,12)))
    >>> a
    array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
    [ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])
    >>> np.hsplit(a,3) # Split a into 3
    [array([[ 9., 5., 6., 3.],
    [ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.],
    [ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.],
    [ 2., 2., 4., 0.]])]
    >>> np.hsplit(a,(3,4)) # Split a after the third and the fourth column
    [array([[ 9., 5., 6.],
    [ 1., 4., 9.]]), array([[ 3.],
    [ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.],
    [ 2., 1., 0., 6., 2., 2., 4., 0.]])]
  • 获取某个轴的最大的元素

    1
    data.max(axis=0)
  • 将数组y中各元素值的符号赋值给数组x对应元素

    1
    np.copysign(x,y)

运算

  • 数组的转置

    1
    2
    3
    a.T
    # 或
    a.transpose()
  • 内积

    1
    a * b
  • 矩阵乘法

    1
    a.dot(b)
  • 累加

    1
    a.cumsum()
  • 开根号

    1
    np.sqrt((2,3))
  • 绝对值

    1
    np.abs(ndarray)
  • 向上取整 (1.2取2 -1.2取-1)

    1
    np.cell(ndarray)
  • 向下取整 (1.2取1 -1.2取-2)

    1
    np.floor(ndarray)
  • 截取数组的整数部分(注意区分np.floor和np.cell)

    1
    np.trunc(ndarray)
  • 四舍五入到给定的小数位

    1
    np.around(ndarray)
  • 四舍五入到最近整数

    1
    np.rint(ndarray)
  • 对数组进行排序

    1
    2
    Z = np.random.random(10)
    Z.sort()
  • np.fromfunction

    1
    2
    3
    4
    >>> def f(x,y):
    ... return 10*x+y
    ...
    >>> b = np.fromfunction(f,(5,4),dtype=int)
  • 矩阵求逆

    1
    2
    3
    >>> np.linalg.inv(a)
    array([[-2. , 1. ],
    [ 1.5, -0.5]])
  • 矩阵的对角线元素和

    1
    2
    >>> np.trace(u)  # trace
    2.0
  • 解线性方程

    1
    2
    3
    4
    	>>> y = np.array([[5.], [7.]])
    >>> np.linalg.solve(a, y)
    array([[-3.],
    [ 4.]])
  • 计算奇异值和右奇异值

    1
    2
    3
    	>>> np.linalg.eig(j)
    (array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j , 0.70710678-0.j ],
    [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))
  • 获取两个数组中的相同值(取交集)

    1
    np.intersect1d(Z1,Z2)
  • 比较两个array是不是每一元素都相近,默认在1e-05的误差范围内

    1
    np.allclose(A,B)
  • 比较两个array是不是形状相同,且每个元素的值都相同

    1
    np.array_equal(A,B)

索引技巧

  • 花式索引

    1
    2
    3
    a = np.arange(0, 100, 10)
    indices = [1, 5, -1]
    b = a[indices]
  • 数组索引赋值操作

    1
    2
    3
    4
    5
    6
    >>> a = np.arange(5)
    >>> a
    array([0, 1, 2, 3, 4])
    >>> a[[1,3,4]] = 0
    >>> a
    array([0, 0, 2, 0, 0])
  • argmax获取最大元素的索引位置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> data
    array([[ 0. , 0.84147098, 0.90929743, 0.14112001],
    [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ],
    [ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
    [-0.53657292, 0.42016704, 0.99060736, 0.65028784],
    [-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
    >>>
    >>> ind = data.argmax(axis=0) # index of the maxima for each series
    >>> ind
    array([2, 0, 3, 1])
  • 布尔屏蔽

    1
    2
    3
    4
    5
    6
    7
    8
    >>> a = np.arange(12).reshape(3,4)
    >>> b = a > 4
    >>> b # b is a boolean with a's shape
    array([[False, False, False, False],
    [False, True, True, True],
    [ True, True, True, True]])
    >>> a[b] # 1d array with the selected elements
    array([ 5, 6, 7, 8, 9, 10, 11])
  • 不完全索引

    1
    2
    a = np.arange(0, 100, 10)
    c = a[a >= 50]
  • 返回一个包含符合指定条件的索引数组

    1
    2
    3
    4
    5
    a = np.arange(0, 100, 10)
    b = np.where(a < 50)
    c = np.where(a >= 50)[0]
    print(b) # >>>(array([0, 1, 2, 3, 4]),)
    print(c) # >>>[5 6 7 8 9]
  • 三个点( … )表示产生完整索引元组所需的冒号

    1
    2
    3
    x[1,2,...] # 等于 x[1,2,:,:,:]。
    x[...,3] # 等效于 x[:,:,:,:,3]。
    x[4,...,5,:] # 等效于 x[4,:,:,5,:]。
  • newaxis扩展一个新的轴

    1
    2
    3
    4
    5
    6
    >>> from numpy import newaxis
    >>> a = np.array([4.,2.])
    >>> a[:,newaxis]

    array([[ 4.],
    [ 2.]])

其他操作

  • 深拷贝和浅拷贝

    1
    2
    3
    a.view() # 获取一个数组的视图,更改视图的内容 a也会更改

    a.copy() # 获取一个数组的完整拷贝,更改拷贝内容 a不会改变
  • 广播(Broadcasting)规则

    • Broadcasting允许通用函数以有意义的方式处理具有不完全相同形状的输入。

    • Broadcasting的第一个规则是,如果所有输入数组不具有相同数量的维度,则“1”将被重复地添加到较小数组的形状,直到所有数组具有相同数量的维度。

    • Broadcasting的第二个规则确保沿着特定维度具有大小为1的数组表现得好像它们具有沿着该维度具有最大形状的数组的大小。假定数组元素的值沿“Broadcasting”数组的该维度相同。

    • 在应用广播规则之后,所有阵列的大小必须匹配。更多细节可以在 Broadcasting 中找到。

  • ix_()函数

    可以使用 ix_ 函数来组合不同的向量以获得每个n-uplet的结果。例如,如果要计算从向量abc中的取得的所有三元组的所有a + b * c

    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
    28
    29
    30
    31
    32
    33
    34
    35
    >>> a = np.array([2,3,4,5])
    >>> b = np.array([8,5,4])
    >>> c = np.array([5,4,6,8,3])
    >>> ax,bx,cx = np.ix_(a,b,c)
    >>> ax
    array([[[2]],
    [[3]],
    [[4]],
    [[5]]])
    >>> bx
    array([[[8],
    [5],
    [4]]])
    >>> cx
    array([[[5, 4, 6, 8, 3]]])
    >>> ax.shape, bx.shape, cx.shape
    ((4, 1, 1), (1, 3, 1), (1, 1, 5))
    >>> result = ax+bx*cx
    >>> result
    array([[[42, 34, 50, 66, 26],
    [27, 22, 32, 42, 17],
    [22, 18, 26, 34, 14]],
    [[43, 35, 51, 67, 27],
    [28, 23, 33, 43, 18],
    [23, 19, 27, 35, 15]],
    [[44, 36, 52, 68, 28],
    [29, 24, 34, 44, 19],
    [24, 20, 28, 36, 16]],
    [[45, 37, 53, 69, 29],
    [30, 25, 35, 45, 20],
    [25, 21, 29, 37, 17]]])
    >>> result[3,2,4]
    17
    >>> a[3]+b[2]*c[4]
    17
  • 忽略numpy错误提示

    1
    2
    with np.errstate(divide='ignore'):
    Z = np.ones(1) / 0
  • 获取昨天,今天,明天

    1
    2
    3
    yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D')
    today = np.datetime64('today', 'D')
    tomorrow = np.datetime64('today', 'D') + np.timedelta64(1, 'D')
  • 获取指定年月区间内的所有日期

    1
    Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
  • 数组类型转换(float转int)

    1
    Z.astype(int)
  • 比np.sum更快的数组求和方式

    1
    2
    Z = np.arange(10)
    np.add.reduce(Z)
  • 设置数组位immutable

    1
    2
    Z = np.zeros(10)
    Z.flags.writeable = False
  • 从文本中加载数据

    1
    2
    3
    4
    5
    6
    7
    8
    from io import StringIO

    # Fake file
    s = StringIO("""1, 2, 3, 4, 5\n
    6, , , 7, 8\n
    , , 9,10,11\n""")
    Z = np.genfromtxt(s, delimiter=",", dtype=np.int)
    print(Z)
  • 在2D数组中随机放置P个元素

    1
    2
    3
    4
    5
    n = 10
    p = 3
    Z = np.zeros((n,n))
    np.put(Z, np.random.choice(range(n*n), p, replace=False),1)
    print(Z)

Numpy反直觉汇总

  • 反直觉的sum运算

    1
    2
    3
    4
    5
    >>> print(sum(range(5),-1))
    9
    >>> from numpy import *
    >>> print(sum(range(5),-1))
    10
  • 反直觉的nan

    1
    2
    3
    4
    >>> print(np.nan == np.nan)
    False
    >>> print(np.nan in set([np.nan]))
    True
  • 反直觉的浮点数

    1
    2
    >>> print(0.3 == 3 * 0.1)
    False
  • 令人迷惑的索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    >>> a = np.arange(12).reshape(3,4)
    >>> b1 = np.array([False,True,True]) # first dim selection
    >>> b2 = np.array([True,False,True,False]) # second dim selection
    >>>
    >>> a[b1,:] # selecting rows
    array([[ 4, 5, 6, 7],
    [ 8, 9, 10, 11]])
    >>>
    >>> a[b1] # same thing
    array([[ 4, 5, 6, 7],
    [ 8, 9, 10, 11]])
    >>>
    >>> a[:,b2] # selecting columns
    array([[ 0, 2],
    [ 4, 6],
    [ 8, 10]])
    >>>
    >>> a[b1,b2] # a weird thing to do
    array([ 4, 10])