1.3.2.1 元素级操作

1.3.2.1.1 基础操作

标量:

In [54]:

  1. a = np.array([1, 2, 3, 4])
  2. a + 1

Out[54]:

  1. array([2, 3, 4, 5])

In [55]:

  1. 2**a

Out[55]:

  1. array([ 2, 4, 8, 16])

所有运算是在元素级别上操作:

In [56]:

  1. b = np.ones(4) + 1
  2. a - b

Out[56]:

  1. array([-1., 0., 1., 2.])

In [57]:

  1. a * b

Out[57]:

  1. array([ 2., 4., 6., 8.])

In [58]:

  1. j = np.arange(5)
  2. 2**(j + 1) - j

Out[58]:

  1. array([ 2, 3, 6, 13, 28])

这些操作当然也比你用纯Python实现好快得多:

In [60]:

  1. a = np.arange(10000)
  2. %timeit a + 1
  1. 100000 loops, best of 3: 11 µs per loop

In [61]:

  1. l = range(10000)
  2. %timeit [i+1 for i in l]
  1. 1000 loops, best of 3: 560 µs per loop

注意:数组相乘不是矩阵相乘:

In [62]:

  1. c = np.ones((3, 3))
  2. c * c # 不是矩阵相乘!

Out[62]:

  1. array([[ 1., 1., 1.],
  2. [ 1., 1., 1.],
  3. [ 1., 1., 1.]])

注:矩阵相乘:

In [63]:

  1. c.dot(c)

Out[63]:

  1. array([[ 3., 3., 3.],
  2. [ 3., 3., 3.],
  3. [ 3., 3., 3.]])

练习:元素级别的操作

  • 试一下元素级别的简单算术操作
  • %timeit 比一下他们与纯Python对等物的时间
  • 生成:
    • [20, 21, 22, 23, 2**4]
    • a_j = 2^(3*j) - j

1.3.2.1.2其他操作

对比:

In [64]:

  1. a = np.array([1, 2, 3, 4])
  2. b = np.array([4, 2, 2, 4])
  3. a == b

Out[64]:

  1. array([False, True, False, True], dtype=bool)

In [65]:

  1. a > b

Out[65]:

  1. array([False, False, True, False], dtype=bool)

数组级别的对比:

In [66]:

  1. a = np.array([1, 2, 3, 4])
  2. b = np.array([4, 2, 2, 4])
  3. c = np.array([1, 2, 3, 4])
  4. np.array_equal(a, b)

Out[66]:

  1. False

In [67]:

  1. np.array_equal(a, c)

Out[67]:

  1. True

逻辑操作

In [68]:

  1. a = np.array([1, 1, 0, 0], dtype=bool)
  2. b = np.array([1, 0, 1, 0], dtype=bool)
  3. np.logical_or(a, b)

Out[68]:

  1. array([ True, True, True, False], dtype=bool)

In [69]:

  1. np.logical_and(a, b)

Out[69]:

  1. array([ True, False, False, False], dtype=bool)

超越函数

In [71]:

  1. a = np.arange(5)
  2. np.sin(a)

Out[71]:

  1. array([ 0\. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ])

In [72]:

  1. np.log(a)
  1. -c:1: RuntimeWarning: divide by zero encountered in log

Out[72]:

  1. array([ -inf, 0\. , 0.69314718, 1.09861229, 1.38629436])

In [73]:

  1. np.exp(a)

Out[73]:

  1. array([ 1\. , 2.71828183, 7.3890561 , 20.08553692, 54.59815003])

形状不匹配

In [74]:

  1. a = np.arange(4)
  2. a + np.array([1, 2])
  1.  ------------- ------------- ------------- ------------- -----------------------
  2. ValueError Traceback (most recent call last)
  3. <ipython-input-74-82c1c1d5b8c1> in <module>()
  4. 1 a = np.arange(4)
  5. ----> 2 a + np.array([1, 2])
  6. ValueError: operands could not be broadcast together with shapes (4,) (2,)

广播?我们将在稍后讨论。

变换

In [76]:

  1. a = np.triu(np.ones((3, 3)), 1) # 看一下 help(np.triu)
  2. a

Out[76]:

  1. array([[ 0., 1., 1.],
  2. [ 0., 0., 1.],
  3. [ 0., 0., 0.]])

In [77]:

  1. a.T

Out[77]:

  1. array([[ 0., 0., 0.],
  2. [ 1., 0., 0.],
  3. [ 1., 1., 0.]])

警告:变换是视图

因此,下列的代码是错误的,将导致矩阵不对称:

In [78]:

  1. a += a.T

注:线性代数

子模块 numpy.linalg 实现了基础的线性代数,比如解开线性系统,奇异值分解等。但是,并不能保证以高效的方式编译,因此,建议使用 scipy.linalg, 详细的内容见线性代数操作:scipy.linalg(暂缺)。

练习:其他操作

  • 看一下 np.allclose 的帮助,什么时候这很有用?
  • 看一下 np.triunp.tril的帮助。