1.3.2.1 元素级操作
1.3.2.1.1 基础操作
标量:
In [54]:
a = np.array([1, 2, 3, 4])
a + 1
Out[54]:
array([2, 3, 4, 5])
In [55]:
2**a
Out[55]:
array([ 2, 4, 8, 16])
所有运算是在元素级别上操作:
In [56]:
b = np.ones(4) + 1
a - b
Out[56]:
array([-1., 0., 1., 2.])
In [57]:
a * b
Out[57]:
array([ 2., 4., 6., 8.])
In [58]:
j = np.arange(5)
2**(j + 1) - j
Out[58]:
array([ 2, 3, 6, 13, 28])
这些操作当然也比你用纯Python实现好快得多:
In [60]:
a = np.arange(10000)
%timeit a + 1
100000 loops, best of 3: 11 µs per loop
In [61]:
l = range(10000)
%timeit [i+1 for i in l]
1000 loops, best of 3: 560 µs per loop
注意:数组相乘不是矩阵相乘:
In [62]:
c = np.ones((3, 3))
c * c # 不是矩阵相乘!
Out[62]:
array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
注:矩阵相乘:
In [63]:
c.dot(c)
Out[63]:
array([[ 3., 3., 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]:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
a == b
Out[64]:
array([False, True, False, True], dtype=bool)
In [65]:
a > b
Out[65]:
array([False, False, True, False], dtype=bool)
数组级别的对比:
In [66]:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
c = np.array([1, 2, 3, 4])
np.array_equal(a, b)
Out[66]:
False
In [67]:
np.array_equal(a, c)
Out[67]:
True
逻辑操作:
In [68]:
a = np.array([1, 1, 0, 0], dtype=bool)
b = np.array([1, 0, 1, 0], dtype=bool)
np.logical_or(a, b)
Out[68]:
array([ True, True, True, False], dtype=bool)
In [69]:
np.logical_and(a, b)
Out[69]:
array([ True, False, False, False], dtype=bool)
In [71]:
a = np.arange(5)
np.sin(a)
Out[71]:
array([ 0\. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ])
In [72]:
np.log(a)
-c:1: RuntimeWarning: divide by zero encountered in log
Out[72]:
array([ -inf, 0\. , 0.69314718, 1.09861229, 1.38629436])
In [73]:
np.exp(a)
Out[73]:
array([ 1\. , 2.71828183, 7.3890561 , 20.08553692, 54.59815003])
形状不匹配
In [74]:
a = np.arange(4)
a + np.array([1, 2])
------------- ------------- ------------- ------------- -----------------------
ValueError Traceback (most recent call last)
<ipython-input-74-82c1c1d5b8c1> in <module>()
1 a = np.arange(4)
----> 2 a + np.array([1, 2])
ValueError: operands could not be broadcast together with shapes (4,) (2,)
广播?我们将在稍后讨论。
变换
In [76]:
a = np.triu(np.ones((3, 3)), 1) # 看一下 help(np.triu)
a
Out[76]:
array([[ 0., 1., 1.],
[ 0., 0., 1.],
[ 0., 0., 0.]])
In [77]:
a.T
Out[77]:
array([[ 0., 0., 0.],
[ 1., 0., 0.],
[ 1., 1., 0.]])
警告:变换是视图
因此,下列的代码是错误的,将导致矩阵不对称:
In [78]:
a += a.T
注:线性代数
子模块 numpy.linalg
实现了基础的线性代数,比如解开线性系统,奇异值分解等。但是,并不能保证以高效的方式编译,因此,建议使用 scipy.linalg
, 详细的内容见线性代数操作:scipy.linalg
(暂缺)。
练习:其他操作
- 看一下
np.allclose
的帮助,什么时候这很有用? - 看一下
np.triu
和np.tril
的帮助。