随机数
numpy.random.permutation
>>> np.random.permutation(10)
array([1, 7, 4, 3, 0, 9, 2, 5, 8, 6])
>>> np.random.permutation([1, 4, 9, 12, 15])
array([15, 1, 9, 4, 12])
>>> arr = np.arange(9).reshape((3, 3))
>>> np.random.permutation(arr)
array([[6, 7, 8],
[0, 1, 2],
[3, 4, 5]])
来源:http://www.jb51.net/article/49397.htm
1、Numpy是什么
很简单,Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy、matplotlib一起使用。其实,list已经提供了类似于矩阵的表示形式,不过numpy为我们提供了更多的函数。如果接触过matlab、scilab,那么numpy很好入手。 在以下的代码示例中,总是先导入了numpy:
>>> import numpy as np
>>> print np.version.version
1.6.2
2、多维数组
多维数组的类型是:numpy.ndarray。
使用numpy.array方法
以list或tuple变量为参数产生一维数组:
>>> print np.array([1,2,3,4])
[1 2 3 4]
>>> print np.array((1.2,2,3,4))
[ 1.2 2. 3. 4. ]
>>> print type(np.array((1.2,2,3,4)))
<type 'numpy.ndarray'>
以list或tuple变量为元素产生二维数组:
>>> print np.array([[1,2],[3,4]])
[[1 2]
[3 4]]
生成数组的时候,可以指定数据类型,例如numpy.int32, numpy.int16, and numpy.float64等:
>>> print np.array((1.2,2,3,4), dtype=np.int32)
[1 2 3 4]
使用numpy.arange方法
>>> print np.arange(15)
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
>>> print type(np.arange(15))
<type 'numpy.ndarray'>
>>> print np.arange(15).reshape(3,5)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
>>> print type(np.arange(15).reshape(3,5))
<type 'numpy.ndarray'>
使用numpy.linspace方法
例如,在从1到3中产生9个数:
>>> print np.linspace(1,3,9)
[ 1. 1.25 1.5 1.75 2. 2.25 2.5 2.75 3. ]
使用numpy.zeros,numpy.ones,numpy.eye等方法可以构造特定的矩阵
>>> print np.zeros((3,4))
[[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]
>>> print np.ones((3,4))
[[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]]
>>> print np.eye(3)
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
创建一个三维数组:
>>> print np.zeros((2,2,2))
[[[ 0. 0.]
[ 0. 0.]]
[[ 0. 0.]
[ 0. 0.]]]
获取数组的属性:
>>> a = np.zeros((2,2,2))
>>> print a.ndim #数组的维数
3
>>> print a.shape #数组每一维的大小
(2, 2, 2)
>>> print a.size #数组的元素数
8
>>> print a.dtype #元素类型
float64
>>> print a.itemsize #每个元素所占的字节数
8
数组索引,切片,赋值
>>> a = np.array( [[2,3,4],[5,6,7]] )
>>> print a
[[2 3 4]
[5 6 7]]
>>> print a[1,2]
7
>>> print a[1,:]
[5 6 7]
>>> print a[1,1:2]
[6]
>>> a[1,:] = [8,9,10]
>>> print a
[[ 2 3 4]
[ 8 9 10]]
>>> for x in np.linspace(1,3,3):
... print x
...
1.0
2.0
3.0
基本的数组运算
先构造数组a、b:
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print a
[[ 1. 1.]
[ 1. 1.]]
>>> print b
[[ 1. 0.]
[ 0. 1.]]
数组的加减乘除:
>>> print a > 2
[[False False]
[False False]]
>>> print a+b
[[ 2. 1.]
[ 1. 2.]]
>>> print a-b
[[ 0. 1.]
[ 1. 0.]]
>>> print b*2
[[ 2. 0.]
[ 0. 2.]]
>>> print (a*2)*(b*2)
[[ 4. 0.]
[ 0. 4.]]
>>> print b/(a*2)
[[ 0.5 0. ]
[ 0. 0.5]]
>>> print (a*2)**4
[[ 16. 16.]
[ 16. 16.]]
使用数组对象自带的方法:
>>> a.sum()
4.0
>>> a.sum(axis=0) #计算每一列(二维数组中类似于矩阵的列)的和
array([ 2., 2.])
>>> a.min()
1.0
>>> a.max()
1.0
使用numpy下的方法:
>>> np.sin(a)
array([[ 0.84147098, 0.84147098],
[ 0.84147098, 0.84147098]])
>>> np.max(a)
1.0
>>> np.floor(a)
array([[ 1., 1.],
[ 1., 1.]])
>>> np.exp(a)
array([[ 2.71828183, 2.71828183],
[ 2.71828183, 2.71828183]])
>>> np.dot(a,a) ##矩阵乘法
array([[ 2., 2.],
[ 2., 2.]])
合并数组
使用numpy下的vstack和hstack函数:
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print np.vstack((a,b))
[[ 1. 1.]
[ 1. 1.]
[ 1. 0.]
[ 0. 1.]]
>>> print np.hstack((a,b))
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
看一下这两个函数有没有涉及到浅拷贝这种问题:
>>> c = np.hstack((a,b))
>>> print c
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
>>> a[1,1] = 5
>>> b[1,1] = 5
>>> print c
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
可以看到,a、b中元素的改变并未影响c。
深拷贝数组
数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些:
>>> a = np.ones((2,2))
>>> b = a
>>> b is a
True
>>> c = a.copy() #深拷贝
>>> c is a
False
基本的矩阵运算
转置:
>>> a = np.array([[1,0],[2,3]])
>>> print a
[[1 0]
[2 3]]
>>> print a.transpose()
[[1 2]
[0 3]]
迹:
>>> print np.trace(a)
4
numpy.linalg模块中有很多关于矩阵运算的方法:
>>> import numpy.linalg as nplg
特征值、特征向量:
>>> print nplg.eig(a)
(array([ 3., 1.]), array([[ 0. , 0.70710678],
[ 1. , -0.70710678]]))
http://blog.csdn.net/hickai/article/details/23431843
1、Numpy是什么
很简单,Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy、matplotlib一起使用。其实,list已经提供了类似于矩阵的表示形式,不过numpy为我们提供了更多的函数。如果接触过matlab、scilab,那么numpy很好入手。 在以下的代码示例中,总是先导入了numpy:
2、多维数组
多维数组的类型是:numpy.ndarray。
使用numpy.array方法
以list或tuple变量为参数产生一维数组:
例如,在从1到3中产生9个数:
例如:
[[ 0. 0.]
[ 0. 0.]]]
数组索引,切片,赋值
示例:
基本的数组运算
先构造数组a、b:
使用数组对象自带的方法:
使用numpy下的方法:
合并数组
使用numpy下的vstack和hstack函数:
看一下这两个函数有没有涉及到浅拷贝这种问题:
深拷贝数组
数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些:
基本的矩阵运算
转置:
特征值、特征向量:
3、矩阵
numpy也可以构造矩阵对象,这里不做讨论。
Numpy简介
Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包。其部分功能如下:
①ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。⑤用于集成由C、C++、Fortran等语言编写的代码的工具。
创建数组
创建数组最简单的办法是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的NumPy数组。以一个列表的转换为例:
基本的索引与切片
通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。
用数组表达式代替循环的做法,通常称为矢量化
将条件逻辑表述为数组运算
Numpy.where函数是三元表达式x if condition else y的矢量化版本
用于布尔型数组的方法
唯一化
来源:http://book.51cto.com/art/201406/441434.htm
1.4.4 学习NumPy(1)
让我们引入NumPy,并小试一下。对此,需要打开Python交互界面。
- >>> import numpy
- >>> numpy.version.full_version
- 1.6.2
由于我们并不想破坏命名空间,所以肯定不能做下面这样的事情:
- >>> from numpy import *
这个numpy.array数组很可能会遮挡住标准Python中包含的数组模块。相反,我们将会采用下面这种便捷方式:
- >>> import numpy as np
- >>> a = np.array([0,1,2,3,4,5])
- >>> a
- array([0, 1, 2, 3, 4, 5])
- >>> a.ndim
- 1
- >>> a.shape
- (6,)
这里只是采用了与在Python中创建列表相类似的方法来创建数组。不过,NumPy数组还包含更多关于数组形状的信息。在这个例子中,它是一个含有5个元素的一维数组。到目前为止,并没有什么令人惊奇的。
现在我们将这个数组转换到一个2D矩阵中:
- >>> b = a.reshape((3,2))
- >>> b
- array([[0, 1],
- [2, 3],
- [4, 5]])
- >>> b.ndim
- 2
- >>> b.shape
- (3, 2)
当我们意识到NumPy包优化到什么程度时,有趣的事情发生了。比如,它在所有可能之处都避免复制操作。
- >>> b[1][0]=77
- >>> b
- array([[ 0, 1],
- [77, 3],
- [ 4, 5]])
- >>> a
- array([ 0, 1, 77, 3, 4, 5])
在这个例子中,我们把b的值从2改成77,然后立刻就会发现相同的改动已经反映在a中。当你需要一个真正的副本时,请记住这个。
- >>> c = a.reshape((3,2)).copy()
- >>> c
- array([[ 0, 1],
- [77, 3],
- [ 4, 5]])
- >>> c[0][0] = -99
- >>> a
- array([ 0, 1, 77, 3, 4, 5])
- >>> c
- array([[-99, 1],
- [ 77, 3],
- [ 4, 5]])
这里,c和a是完全独立的副本。
NumPy数组还有一大优势,即对数组的操作可以传递到每个元素上。
- >>> a*2
- array([ 2, 4, 6, 8, 10])
- >>> a**2
- array([ 1, 4, 9, 16, 25])
- Contrast that to ordinary Python lists:
- >>> [1,2,3,4,5]*2
- [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
- >>> [1,2,3,4,5]**2
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: unsupported operand type(s) for ** or pow(): 'list' and
- 'int'
当然,我们在使用NumPy数组的时候会牺牲Python列表所提供的一些敏捷性。像相加、删除这样的简单操作在NumPy数组中会有一点麻烦。幸运的是,这两种方式都可以使用。我们可以根据手头上的任务来选择最适合的那种。
1. 索引
NumPy的部分威力来自于它的通用数组访问方式。
除了正常的列表索引方式,它还允许我们将数组本身当做索引使用。
- >>> a[np.array([2,3,4])]
- array([77, 3, 4])
- >>> a>4
- array([False, False, True, False, False, True], dtype=bool)
- >>> a[a>4]
- array([77, 5])
这还可用于修剪异常值。
- >>> a[a>4] = 4
- >>> a
- array([0, 1, 4, 3, 4, 4])
鉴于这是一个经常碰到的情况,所以这里有一个专门的修剪函数来处理它。如下面的函数调用所示,它将数组值超出某个区间边界的部分修剪掉。
- >>> a.clip(0,4)
- array([0, 1, 4, 3, 4, 4])
2. 处理不存在的值
当我们预处理刚从文本文件中读出的数据时,NumPy的索引能力就派上用场了。这些数据中很可能包含不合法的值,我们像下面这样用numpy.NAN做标记,来表示它不是真实数值。
- c = np.array([1, 2, np.NAN, 3, 4]) # 假设已经从文本文件中读取了数据
- >>> c
- array([ 1., 2., nan, 3., 4.])
- >>> np.isnan(c)
- array([False, False, True, False, False], dtype=bool)
- >>> c[~np.isnan(c)]
- array([ 1., 2., 3., 4.])
- >>> np.mean(c[~np.isnan(c)])
- 2.5
3. 运行时行为比较
让我们比较一下NumPy和标准Python列表的运行时行为。在下面这些代码中,我们将会计算从1到1000的所有数的平方和,并观察这些计算花费了多少时间。为了使评估足够准确,我们重复做了10 000次,并记录下总时间。
- import timeit
- normal_py_sec = timeit.timeit('sum(x*x for x in xrange(1000))',
- number=10000)
- naive_np_sec = timeit.timeit('sum(na*na)',
- setup="import numpy as np; na=np.arange(1000)",
- number=10000)
- good_np_sec = timeit.timeit('na.dot(na)',
- setup="import numpy as np; na=np.arange(1000)",
- number=10000)
- print("Normal Python: %f sec"%normal_py_sec)
- print("Naive NumPy: %f sec"%naive_np_sec)
- print("Good NumPy: %f sec"%good_np_sec)
- Normal Python: 1.157467 sec
- Naive NumPy: 4.061293 sec
- Good NumPy: 0.033419 sec
我们观察到两个有趣的现象。首先,仅用NumPy作为数据存储(原始NumPy)时,花费的时间竟然是标准Python列表的3.5倍。这让我们感到非常惊奇,因为我们原本以为既然它是C扩展,那肯定要快得多。对此,一个解释是,在Python中访问个体数组元素是相当耗时的。只有当我们在优化后的扩展代码中使用一些算法之后,才能获得速度上的提升。一个巨大的提升是:当使用NumPy的dot()函数之后,可以得到25倍的加速。总而言之,在要实现的算法中,应该时常考虑如何将数组元素的循环处理从Python中移到一些高度优化的NumPy或SciPy扩展函数中。
然而,速度也是有代价的。当使用NumPy数组时,我们不再拥有像Python列表那样基本上可以装下任何数据的不可思议的灵活性。NumPy数组中只有一个数据类型。
- >>> a = np.array([1,2,3])
- >>> a.dtype
- dtype('int64')
如果尝试使用不同类型的元素,NumPy会尽量把它们强制转换为最合理的常用数据类型:
- >>> np.array([1, "stringy"])
- array(['1', 'stringy'], dtype='|S8')
- >>> np.array([1, "stringy", set([1,2,3])])
- array([1, stringy, set([1, 2, 3])], dtype=object)
- >>> a>4
- array([False, False, True, False, False, True], dtype=bool)
- >>> a[a>4]
- array([77, 5])
这还可用于修剪异常值。
- >>> a[a>4] = 4
- >>> a
- array([0, 1, 4, 3, 4, 4])
鉴于这是一个经常碰到的情况,所以这里有一个专门的修剪函数来处理它。如下面的函数调用所示,它将数组值超出某个区间边界的部分修剪掉。
- >>> a.clip(0,4)
- array([0, 1, 4, 3, 4, 4])
2. 处理不存在的值
当我们预处理刚从文本文件中读出的数据时,NumPy的索引能力就派上用场了。这些数据中很可能包含不合法的值,我们像下面这样用numpy.NAN做标记,来表示它不是真实数值。
- c = np.array([1, 2, np.NAN, 3, 4]) # 假设已经从文本文件中读取了数据
- >>> c
- array([ 1., 2., nan, 3., 4.])
- >>> np.isnan(c)
- array([False, False, True, False, False], dtype=bool)
- >>> c[~np.isnan(c)]
- array([ 1., 2., 3., 4.])
- >>> np.mean(c[~np.isnan(c)])
- 2.5
3. 运行时行为比较
让我们比较一下NumPy和标准Python列表的运行时行为。在下面这些代码中,我们将会计算从1到1000的所有数的平方和,并观察这些计算花费了多少时间。为了使评估足够准确,我们重复做了10 000次,并记录下总时间。
- import timeit
- normal_py_sec = timeit.timeit('sum(x*x for x in xrange(1000))',
- number=10000)
- naive_np_sec = timeit.timeit('sum(na*na)',
- setup="import numpy as np; na=np.arange(1000)",
- number=10000)
- good_np_sec = timeit.timeit('na.dot(na)',
- setup="import numpy as np; na=np.arange(1000)",
- number=10000)
- print("Normal Python: %f sec"%normal_py_sec)
- print("Naive NumPy: %f sec"%naive_np_sec)
- print("Good NumPy: %f sec"%good_np_sec)
- Normal Python: 1.157467 sec
- Naive NumPy: 4.061293 sec
- Good NumPy: 0.033419 sec
我们观察到两个有趣的现象。首先,仅用NumPy作为数据存储(原始NumPy)时,花费的时间竟然是标准Python列表的3.5倍。这让我们感到非常惊奇,因为我们原本以为既然它是C扩展,那肯定要快得多。对此,一个解释是,在Python中访问个体数组元素是相当耗时的。只有当我们在优化后的扩展代码中使用一些算法之后,才能获得速度上的提升。一个巨大的提升是:当使用NumPy的dot()函数之后,可以得到25倍的加速。总而言之,在要实现的算法中,应该时常考虑如何将数组元素的循环处理从Python中移到一些高度优化的NumPy或SciPy扩展函数中。
然而,速度也是有代价的。当使用NumPy数组时,我们不再拥有像Python列表那样基本上可以装下任何数据的不可思议的灵活性。NumPy数组中只有一个数据类型。
- >>> a = np.array([1,2,3])
- >>> a.dtype
- dtype('int64')
如果尝试使用不同类型的元素,NumPy会尽量把它们强制转换为最合理的常用数据类型:
- >>> np.array([1, "stringy"])
- array(['1', 'stringy'], dtype='|S8')
- >>> np.array([1, "stringy", set([1,2,3])])
- array([1, stringy, set([1, 2, 3])], dtype=object)