numpy 基础入门 - 30分钟学会numpy

Numpy简单介绍

1.Numpy是什么

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

1

2

3

>>> import numpy as np  

>>> print np.version.version  

1.6.2

2. 多维数组

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

使用numpy.array方法

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

1

2

3

4

5

6

>>> 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变量为元素产生二维数组或者多维数组:

1

2

3

4

5

6

7

8

>>> x = np.array(((1,2,3),(4,5,6)))  

>>> x  

array([[1, 2, 3],  

       [4, 5, 6]])  

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

>>> y  

array([[1, 2, 3],  

       [4, 5, 6]])

 

numpy数据类型设定与转换

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

1

2

3

4

5

6

7

8

numeric_strings2 = np.array(['1.23','2.34','3.45'],dtype=np.string_)  

numeric_strings2  

Out[32]:   

array(['1.23''2.34''3.45'],   

      dtype='|S4')  

   

numeric_strings2.astype(float)  

Out[33]: array([ 1.23,  2.34,  3.45])

 

numpy索引与切片

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

1

2

3

4

5

>>> x[1,2]  

6  

>>> y=x[:,1]  

>>> y  

array([2, 5])

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

1

2

3

4

5

6

7

8

>>> y  

array([2, 5])  

>>> y[0] = 10  

>>> y  

array([10,  5])  

>>> x  

array([[ 1, 10,  3],  

       [ 4,  5,  6]])

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

arr = np.arange(10)  

   

arr  

Out[45]: array([0123456789])  

   

arr[4]  

Out[46]: 4  

   

arr[3:6]  

Out[47]: array([345])  

   

arr[3:6= 12  

   

arr  

Out[49]: array([ 0,  1,  2121212,  6,  7,  8,  9])

 

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

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

 

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

1

2

3

4

5

6

arr_copy = arr[3:6].copy()  

arr_copy[:]=24  

arr_copy  

Out[54]: array([242424])  

arr  

Out[55]: array([ 0,  1,  2121212,  6,  7,  8,  9])

再看下对list 切片修改

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

l=range(10)  

   

l  

Out[35]: [0123456789]  

   

l[5:8= 12  

Traceback (most recent call last):  

   

  File "<ipython-input-36-022af3ddcc9b>", line 1in <module>  

    l[5:8= 12  

   

TypeError: can only assign an iterable  

   

l1= l[5:8]  

   

l1  

Out[38]: [567]  

   

l1[0]=12  

   

l1  

Out[40]: [1267]  

   

l  

Out[41]: [0123456789]

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

 

多维数组索引、切片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

arr2d = np.arange(1,10).reshape(3,3)  

   

arr2d  

Out[57]:   

array([[123],  

       [456],  

       [789]])  

   

arr2d[2]  

Out[58]: array([789])  

   

arr2d[0][2]  

Out[59]: 3  

   

arr2d[0,2]  

Out[60]: 3

 

布尔型索引

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

1

2

3

names = np.array(['Bob','joe','Bob','will'])  

names == 'Bob'  

Out[70]: array([ TrueFalse,  TrueFalse], dtype=bool)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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.84316735,  0.        ],  

       1.34023966,  1.12766186,  1.12507441,  0.        ],  

       1.27392366,  0.        ,  0.        ,  1.60731881],  

       0.23361565,  1.38772715,  0.69129479,  0.        ],  

       0.51353082,  0.17696698,  0.        ,  0.80448168],  

       0.21773096,  0.60582802,  0.        ,  0.83131122],  

       0.50569072,  0.04431685,  0.        ,  0.        ]])

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

 

数组文件输入输出

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

 

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

1

2

3

4

arr = np.arange(10)  

np.save('some_array',arr)  

np.load('some_array.npy')  

Out[80]: array([0123456789])

存取文本文件:

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

arr = np.loadtxt('dataMatrix.txt',delimiter=' ')  

arr  

Out[82]:   

array([[ 1.        ,  1.        ,  1.        ,  1.        ,  1.        ,  

         0.8125    ],  

       0.52882353,  0.56271186,  0.48220588,  0.53384615,  0.61651376,  

         0.58285714],  

       0.        ,  0.        ,  0.        ,  1.        ,  1.        ,  

         1.        ],  

       1.        ,  0.92857143,  0.91857143,  1.        ,  1.        ,  

         1.        ],  

       1.        ,  1.        ,  1.        ,  1.        ,  1.        ,  

         1.        ],  

       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.04803279,  0.08203125,  0.05516667,  0.05517241,  0.04953488,  

         0.05591549]])

 

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

 

使用numpy.arange方法

1

2

3

4

5

6

7

8

9

10

>>> 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到10中产生20个数:

1

2

3

4

5

>>> print np.linspace(1,10,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.        ]

 

使用numpy.zeros,numpy.ones,numpy.eye等方法可以构造特定的矩阵

1

2

3

4

5

6

7

8

9

10

11

12

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

 

获取数组的属性

1

2

3

4

5

6

7

8

9

10

11

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

 

合并数组

使用numpy下的vstack(垂直方向)和hstack(水平方向)函数:

1

2

3

4

5

6

7

8

9

10

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

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

1

2

3

4

5

6

7

8

9

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

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

 

深拷贝数组

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

1

2

3

4

5

6

7

>>> a = np.ones((2,2))  

>>> b = a  

>>> b is a  

True  

>>> c = a.copy()  #深拷贝  

>>> c is a  

False

 

基本的矩阵运算

转置:

1

2

3

4

5

6

7

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

>>> print a  

[[1 0]  

 [2 3]]  

>>> print a.transpose()  

[[1 2]  

 [0 3]]

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

 

特征值、特征向量:

1

2

3

4

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

>>> nplg.eig(a)  

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

       [ 1.        , -0.70710678]]))

 

转自:https://m.pythontab.com/article/1271

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值