Python 30分钟学会numpy实现方法

对python这个高级语言感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧!

Numpy简单介绍

1.Numpy是什么

很简单,Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy、matplotlib一起使用。其实,list已经提供了类似于矩阵的表示形式,不过numpy为我们提供了更多的函数。如果接触过matlab、scilab,那么numpy很好入手。 在以下的代码示例中,总是先导入了numpy:(通用做法import numpu as np 简单输入)


>>> import numpy as np  
>>> print np.version.version  
1.6.2

# End www.jb51.cc

2. 多维数组

多维数组的类型是:numpy.ndarray

使用numpy.array方法

以list或tuple变量为参数产生一维数组:


>>> print np.array([1,2,3,4])  
[1 2 3 4]  
>>> print np.array((1.2,4))  
[ 1.2  2.   3.   4. ]  
>>> print type(np.array((1.2,4)))  
<type 'numpy.ndarray'>

# End www.jb51.cc

以list或tuple变量为元素产生二维数组或者多维数组:


>>> x = np.array(((1,3),(4,5,6)))  
>>> x  
array([[1,3],[4,6]])  
>>> y = np.array([[1,6]])  
>>> y  
array([[1,6]])

# End www.jb51.cc

 

numpy数据类型设定与转换

numpy ndarray数据类型可以通过参数dtype 设定,而且可以使用astype转换类型,在处理文件时候这个会很实用,注意astype 调用会返回一个新的数组,也就是原始数据的一份拷贝。


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

numeric_strings2 = np.array(['1.23','2.34','3.45'],dtype=np.string_)  
numeric_strings2  
Out[32]:   
array(['1.23',dtype='|S4')  
  
numeric_strings2.astype(float)  
Out[33]: array([ 1.23,2.34,3.45])

# End www.jb51.cc

 

numpy索引与切片

index 和slicing :第一数值类似数组横坐标,第二个为纵坐标


>>> x[1,2]  
6  
>>> y=x[:,1]  
>>> y  
array([2,5])

# End www.jb51.cc

涉及改变相关问题,我们改变上面y是否会改变x?这是特别需要关注的!


>>> y  
array([2,5])  
>>> y[0] = 10  
>>> y  
array([10,5])  
>>> x  
array([[ 1,10,[ 4,6]])

# End www.jb51.cc

通过上面可以发现改变y会改变x ,因而我们可以推断,y和x指向是同一块内存空间值,系统没有为y 新开辟空间把x值赋值过去。


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

arr = np.arange(10)  
  
arr  
Out[45]: array([0,1,4,6,7,8,9])  
  
arr[4]  
Out[46]: 4  
  
arr[3:6]  
Out[47]: array([3,5])  
  
arr[3:6] = 12  
  
arr  
Out[49]: array([ 0,12,9])

# End www.jb51.cc

 

如上所示:当将一个标量赋值给切片时,该值会自动传播整个切片区域,这个跟列表最重要本质区别,数组切片是原始数组的视图,视图上任何修改直接反映到源数据上面。

思考为什么这么设计? Numpy 设计是为了处理大数据,如果切片采用数据复制话会产生极大的性能和内存消耗问题。

 

假如说需要对数组是一份副本而不是视图可以如下操作:


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

arr_copy = arr[3:6].copy()  
arr_copy[:]=24  
arr_copy  
Out[54]: array([24,24,24])  
arr  
Out[55]: array([ 0,9])

# End www.jb51.cc

再看下对list 切片修改


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

l=range(10)  
  
l  
Out[35]: [0,9]  
  
l[5:8] = 12  
Traceback (most recent call last):  
  
  File <ipython-input-36-022af3ddcc9b>,line 1,in <module>  
    l[5:8] = 12  
  
TypeError: can only assign an iterable  
  
l1= l[5:8]  
  
l1  
Out[38]: [5,7]  
  
l1[0]=12  
  
l1  
Out[40]: [12,7]  
  
l  
Out[41]: [0,9]

# End www.jb51.cc

这里设计到python 中深浅拷贝,其中切片属于浅拷贝

 

多维数组索引、切片


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

arr2d = np.arange(1,10).reshape(3,3)  
  
arr2d  
Out[57]:   
array([[1,6],[7,9]])  
  
arr2d[2]  
Out[58]: array([7,9])  
  
arr2d[0][2]  
Out[59]: 3  
  
arr2d[0,2]  
Out[60]: 3

# End www.jb51.cc

 

布尔型索引

这种类型在实际代码中出现比较多,关注下。


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

names = np.array(['Bob','joe','Bob','will'])  
names == 'Bob'  
Out[70]: array([ True,False,True,False],dtype=bool)

# End www.jb51.cc

# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

data  
Out[73]:   
array([[ 0.36762706,-1.55668952,0.84316735,-0.116842  ],[ 1.34023966,1.12766186,1.12507441,-0.68689309],[ 1.27392366,-0.43399617,-0.80444728,1.60731881],[ 0.23361565,1.38772715,0.69129479,-1.19228023],[ 0.51353082,0.17696698,-0.06753478,0.80448168],[ 0.21773096,0.60582802,-0.46446071,0.83131122],[ 0.50569072,0.04431685,-0.69358155,-0.9629124 ]])  
  
data[data < 0] = 0  
  
data  
Out[75]:   
array([[ 0.36762706,0.,0.        ],0.        ]])

# End www.jb51.cc

上面展示通过布尔值来设置值的手段。

 

数组文件输入输出

在跑实验时经常需要用到读取文件中的数据,其实在numpy中已经有成熟函数封装好了可以使用

 

将数组以二进制形式格式保存到磁盘,np.save 、np.load 函数是读写磁盘的两个主要函数认情况下,数组以未压缩的原始二进制格式保存在扩展名为.npy的文件


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

arr = np.arange(10)  
np.save('some_array',arr)  
np.load('some_array.npy')  
Out[80]: array([0,9])

# End www.jb51.cc

存取文本文件

文本中存放是聚类需要数据,直接可以方便读取到numpy array中,省去一行行读文件繁琐。


# @param numpy 基础入门 - 30分钟学会numpy
# @author 编程之家 jb51.cc|www.www.jb51.cc 

arr = np.loadtxt('dataMatrix.txt',delimiter=' ')  
arr  
Out[82]:   
array([[ 1.,1.,0.8125    ],[ 0.52882353,0.56271186,0.48220588,0.53384615,0.61651376,0.58285714],[ 0.,1.        ],[ 1.,0.92857143,0.91857143,[ 0.05285714,0.10304348,0.068,0.06512821,0.05492308,0.05244898],[ 0.04803279,0.08203125,0.05516667,0.05517241,0.04953488,0.05591549],0.05591549]])

# End www.jb51.cc

 

np.savetxt 执行相反的操作,这两个函数在跑实验加载数据时可以提供很多便利!!!

 

使用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'>

# End www.jb51.cc

 

使用numpy.linspace方法

例如,在从1到10中产生20个数:


>>> print np.linspace(1,20)  
[  1.           1.47368421   1.94736842   2.42105263   2.89473684  
   3.36842105   3.84210526   4.31578947   4.78947368   5.26315789  
   5.73684211   6.21052632   6.68421053   7.15789474   7.63157895  
   8.10526316   8.57894737   9.05263158   9.52631579  10.        ]

# End www.jb51.cc

 

使用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.]]

# End www.jb51.cc

 

获取数组的属性


>>> a = np.zeros((2,2))  
>>> print a.ndim   #数组的维数  
3  
>>> print a.shape  #数组每一维的大小  
(2,2)  
>>> print a.size   #数组的元素数  
8  
>>> print a.dtype  #元素类型  
float64  
>>> print a.itemsize  #每个元素所占的字节数  
8

# End www.jb51.cc

 

合并数组

使用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.]]

# End www.jb51.cc

看一下这两个函数有没有涉及到浅拷贝这种问题:


>>> 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.]]

# End www.jb51.cc

通过上面可以知道,这里进行是深拷贝,而不是引用指向同一位置的浅拷贝。

 

深拷贝数组

数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些:


>>> a = np.ones((2,2))  
>>> b = a  
>>> b is a  
True  
>>> c = a.copy()  #深拷贝  
>>> c is a  
False

# End www.jb51.cc

 

基本的矩阵运算

转置:


>>> a = np.array([[1,0],[2,3]])  
>>> print a  
[[1 0]  
 [2 3]]  
>>> print a.transpose()  
[[1 2]  
 [0 3]]

# End www.jb51.cc

numpy.linalg模块中有很多关于矩阵运算的方法

 

特征值、特征向量:


>>> a = np.array([[1,3]])  
>>> nplg.eig(a)  
(array([ 3.,1.]),array([[ 0.,0.70710678],-0.70710678]]))

# End www.jb51.cc

相关文章

在前一篇博客中我们介绍了加侧旋的乒乓球弧圈技术的模拟,本...
在近期conda的版本更新中,有可能会删除路径下的_sysconfigd...
本文主要展示了一些lambda表达式的使用示例,通过这些示例,...
本文通过对比Jax和Numpy计算Normalized Hamming Distance的过...
我们知道GPU加速在可并行化程度比较高的算法中,能够发挥出比...
Numpy这个库在Python编程中非常的常用,不仅在性能上补足了P...