numpy 是一个科学计算的库,可以用当做数组使用,提供了矩阵计算的功能,有很多强大的函数。
用 numpy 创建数组和平常创建数组基本一样,还有创建多维数组,创建元组,和查看数据类型,只不过数组的元素都必须是数字。
>>> import numpy as np
>>> print np.version.version
1.6.1
>>> a = np.array([1,2,3,4,5])
>>> a
array([1, 2, 3, 4, 5])
>>> type(a)
<type 'numpy.ndarray'>
>>> a.dtype
dtype('int32')
>>> b = np.array(['a','b',3,a])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot set an array element with a sequence
>>> b = np.array((5,6,7,8,2))
>>> b
array([5, 6, 7, 8, 2])
>>> c = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> len(c)
3
>>> c
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
数组的大小可以通过 len 函数或者是其 shape 属性或是其 size 属性获得,也可以通过其 shape 属性修改。
>>> a = np.array([1,2,3,4,5])
>>> a
array([1, 2, 3, 4, 5])
>>> c = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> c
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> len(a)
5
>>> a.shape
(5,)
>>> c.shape
(3, 3)
>>> c = np.array([[1,2,3,4],[4,5,6,7],[8,9,10,11]])
>>> c
array([[ 1, 2, 3, 4],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> c.shape
(3, 4)
>>> c.shape = 4,3
>>> c
>>> c.size
12
array([[ 1, 2, 3],
[ 4, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>> c.shape = 2,-1
>>> c
array([[ 1, 2, 3, 4, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
可以通过 reshape 方法改变数组的尺寸,得到一个新的数组,原数组不变,而且两个数组共享数据存储空间,修改一个数组内容将会影响另一个数组。
>>> a = np.array([1,2,3,4])
>>> a
array([1, 2, 3, 4])
>>> b = a.reshape((2,2))
>>> b
array([[1, 2],
[3, 4]])
>>> a[0]=10
>>> a
array([10, 2, 3, 4])
>>> b
array([[10, 2],
[ 3, 4]])
无论是 shape 还是 reshape ,修改后的 size 都必须和原数组 size 相同
可以通过 dtype 属性获得数组里元素的类型,也可以通过 dtype 属性来设定元素类型。
>>> a = np.array([1,2,3,4])
>>> a
array([1, 2, 3, 4])
>>> a.dtype
dtype('int32')
>>> b = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]],dtype=np.float)
>>> b
array([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]])
>>> b.dtype
dtype('float64')
>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.complex)
array([[ 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j],
[ 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j],
[ 7.+0.j, 8.+0.j, 9.+0.j, 10.+0.j]])
像 Python 里的数组除了直接创建之外,还可以使用某些函数式表达来生成数组,在 numpy 中则可以使用一些类似 range 的方法生成数组。
- arange函数类似于 python 的 range 函数,通过指定开始值、终值和步长来创建一维数组,注意数组不包括终值:
>>> np.arange(1,2,0.1)
array([ 1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9])
- 还可以使用 zeros, ones, empty, (eye) 函数分别创建一个全零,全一,或者内容随机的数组,默认的数组元素类型是 float64
>>> np.zeros(5)
array([ 0., 0., 0., 0., 0.])
>>> np.ones([2,3])
array([[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> np.ones((2,3,3), dtype=np.int16)
array([[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]], dtype=int16)
>>> np.empty((2,3,3), dtype=np.int16)
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]], dtype=int16)
>>> np.empty((2,3,3))
array([[[ 3.77327817e-297, 1.44929728e-291, 1.43454415e-294],
[ 1.43447248e-294, 1.40295953e-294, 1.37326233e-294],
[ 5.47188794e-297, 1.44933398e-291, 1.43444859e-294]],
[[ 3.19773450e-297, 2.02060385e-294, 2.02136838e-294],
[ 1.32093984e-294, 1.43250740e-294, 1.43571484e-294],
[ 7.84869104e-292, 7.84899687e-292, 1.90821801e-294]]])
- linspace 函数通过指定开始值、终值和元素个数来创建一维数组,可以通过 endpoint 关键字指定是否包括终值,缺省设置是包括终值:
>>> np.linspace(1,2,10)
array([ 1. , 1.11111111, 1.22222222, 1.33333333, 1.44444444,
1.55555556, 1.66666667, 1.77777778, 1.88888889, 2. ])
- logspace 函数和 linspace 类似,不过它创建 10 的 n 次方 的等比数列,下面的例子产生10(10^1)到100(10^2)、有 10 个元素的等比数列:
>>> np.logspace(1,2,10)
array([ 10. , 12.91549665, 16.68100537, 21.5443469 ,
27.82559402, 35.93813664, 46.41588834, 59.94842503,
77.42636827, 100. ])
- 还可以使用 frombuffer, fromstring, fromfile 等函数从字节序列创建数组
>>> np.fromstring('abcdefgh', dtype=np.int8)
array([ 97, 98, 99, 100, 101, 102, 103, 104], dtype=int8)
>>> np.fromstring('abcdefgh', dtype=np.int16)
array([25185, 25699, 26213, 26727], dtype=int16)
>>> 98*256+97
25185
可以看到内存中是以小端序来保存数据的,以相邻的两个字节表示一个 16 比特的整数。
还可以把整个字符串转化为一个 64 位的双精度浮点数组
>>> np.fromstring('abcdefgh', dtype=np.float)
array([ 8.54088322e+194])
- 从函数中创建数组 fromfunction
>>> def func(i):
... return i%4 + 1
...
>>> np.fromfunction(func, (10,))
array([ 1., 2., 3., 4., 1., 2., 3., 4., 1., 2.])
fromfunction 的第一个参数为计算数组元素的函数,第二个参数为数组的大小 shape ,因为它支持多维数组,所以第二个参数为一个序列
创建 九九乘法表
>>> def multable(i, j):
... return (i+1) * (j+1)
...
>>> np.fromfunction(multable, (9,9))
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.],
[ 2., 4., 6., 8., 10., 12., 14., 16., 18.],
[ 3., 6., 9., 12., 15., 18., 21., 24., 27.],
[ 4., 8., 12., 16., 20., 24., 28., 32., 36.],
[ 5., 10., 15., 20., 25., 30., 35., 40., 45.],
[ 6., 12., 18., 24., 30., 36., 42., 48., 54.],
[ 7., 14., 21., 28., 35., 42., 49., 56., 63.],
[ 8., 16., 24., 32., 40., 48., 56., 64., 72.],
[ 9., 18., 27., 36., 45., 54., 63., 72., 81.]])
数组的存取方式和 Python 的列表一致,支持下标索引,切片操作等。
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[5]
5
>>> a[3:5]
array([3, 4])
>>> a[:-1]
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> a[1:3] = 10, 100
>>> a
array([ 0, 10, 100, 3, 4, 5, 6, 7, 8, 9])
在 Python 中,对列表进行切片操作后得到的是一个新的列表,然而对数组的切片操作之后得到的只是原数组的一部分,与原数组共享内存空间。
>>> b = a[3:7]
>>> b
array([3, 4, 5, 6])
>>> b[0]=10
>>> b
array([10, 4, 5, 6])
>>> a
array([ 0, 10, 100, 10, 4, 5, 6, 7, 8, 9])
除了使用下标索引之外,还 NumPy 还提供了两种存取数组的高级方法