入门Numpy

一.NumPy的引入

      标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。

      此外Python还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,也没有各种运算函数,因此也不适合做数值运算。

     NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray(下文统一称之为数组)是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。

Examples:

Python中的列表中的元素不能直接相加减。

例如:

>>>a=[1,2,3]

>>>b=[1,2,3]

>>>a+b

[1, 2, 3, 1, 2, 3]

最佳的方式是将列表转换成Python中的科学计算包numpy包的array类型,再进行加减。

import numpy as np

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

.>>>b = np.array([7,8,9,10])

.>>>a + b

array([ 8, 10, 12, 14])

二.ndarray对象

import numpy as np

1.手动创建

(1)首先需要创建数组才能对其进行其它操作。

1)我们可以通过给array函数传递Python的序列对象创建数组

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

>>> b = np.array((5, 6, 7, 8))

2).如果传递的是多层嵌套的序列,将创建多维数组(下例中的变量c):

>>> c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])

>>> c

array([[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]])

(2)数组的大小可以通过其shape属性获得

>>> a.shape

(4,)

>>> c.shape

(3, 4)

数组a的shape只有一个元素,因此它是一维数组。

数组c的shape有两个元素,因此它是二维数组,其中第0轴的长度为3,第1轴的长度为4。

1).可以通过修改数组的shape属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度。

下面的例子将数组c的shape改为(4,3),注意从(3,4)改为(4,3)并不是对数组进行转置,而只是改变每个轴的大小,数组元素在内存中的位置并没有改变:

>>> c.shape = 4,3

>>> c

array([[ 1, 2, 3], [ 4, 4, 5], [ 6, 7, 7], [ 8, 9, 10]])

2).当某个轴的元素为-1时,将根据数组元素的个数自动计算此轴的长度

因此下面的程序将数组c的shape改为了(2,6):

>>> c.shape = 2,-1

>>> c

array([[ 1, 2, 3, 4, 4, 5], [ 6, 7, 7, 8, 9, 10]])

3).使用数组的reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变:

>>> d = a.reshape((2,2))

>>>d

array([[1, 2],

[3, 4]])

>>>a

 array([1, 2, 3, 4])

数组a和d其实共享数据存储内存区域,因此修改其中任意一个数组的元素都会同时修改另外一个数组的内容:

>>> a[1] = 100 # 将数组a的第一个元素改为100

>>> d # 注意数组d中的2也被改变了

array([[ 1, 100], [ 3, 4]])

>>>a

array([  1, 100,  3,  4])

(3)数组的元素类型可以通过dtype属性获得。

上面例子中的参数序列的元素都是整数,因此所创建的数组的元素类型也是整数,并且是32bit的长整型。可以通过dtype参数在创建时指定元素类型:

>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.float)

array([[ 1., 2., 3., 4.], [ 4., 5., 6., 7.], [ 7., 8., 9., 10.]])

>>> 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序列,然后通过array函数将其转换为数组,这样做显然效率不高。因此NumPy提供了很多专门用来创建数组的函数。

2.函数创建

(1)np.zeros(shape, dtype=float, order='C')  

按照给定的shape(数组维度)和type(元素类型)建立元素都是0的一维或多维数组

shape :int or sequence of ints

dtype :data-type, optional    e.g., `numpy.int8`. Default is`numpy.float64`.

Examples

>>>np.zeros(3)

array([ 0.,  0.,  0.])

>>>np.zeros((3,2))

array([[ 0.,  0.],

[ 0.,  0.],

[ 0.,  0.]])

(2)np.empty(shape, dtype=float, order='C')

按照给定的shape和type返回一个新数组,没有初始化的项,不像“zeros”,不会设置元素值为0

和np.zeros都可用来初始化数组

Examples

>>>np.empty(2)

 array([  2.48675631e-316,   2.48960707e-316])

>>> np.empty([2, 2])

array([[ -9.74499359e+001, 6.69583040e-309],

[ 2.13182611e-314, 3.06959433e-309]]) #random

(3)np.tile(A, reps)

构建一个数组:重复A元素 reps次来构建一个数组

>>>target=np.array([1, 0.2])

>>>np.tile(target, (4, 1))

array([[ 1. ,  0.2],

[ 1. ,  0.2],

[ 1. ,  0.2],

[ 1. ,  0.2]])

>>>np.tile(target, 4)

array([ 1. ,  0.2,  1. ,  0.2,  1. ,  0.2,  1. ,  0.2])

(4)np.randint(low, high=None, size=None)

返回一个随机整数数组,元素的大小是服从左闭右开区间[`low`, `high`)上的‘离散均匀分布’,数组维度为size

Parameters

low : 整数 , 最小的数,除非high是None,此时low是最大的数,元素的范围就是在区间[0,'low')

high : 整数 ,最大的数,是可选的参数

size : 整数或者一个整数元组, 是可选的,代表了构建数组的维度, I比如:`(m, n, k)``, 表示``m * n * k``的数组 . 默认是None,此时返回单个的值

Examples

>>> np.random.randint(2, size=10)

array([1, 0, 0, 0, 1, 1, 0, 0, 1, 0])

>>> np.random.randint(1, size=10)

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Generate a 2 x 4 array of ints between 0 and 4, inclusive:

>>> np.random.randint(5, size=(2, 4))

array([[4, 0, 2, 1],

[3, 2, 2, 0]])

(5)np.sum(a, axis=None, dtype=None, out=None, keepdims=False):

按照给定的维度求数组的元素和

Parameters

a : 类似于array,需要求和的元素

axis :求和的维度,`axis` 的默认值是 `None,是对所有的元素进行求和

Examples

>>> np.sum([0.5, 1.5])

2.0

>>> np.sum([0.5, 0.7, 0.2, 1.5], dtype=np.int32)

1

>>> np.sum([[0, 1], [0, 5]])

6

>>> np.sum([[0, 1], [0, 5]], axis=0)

array([0, 6])

>>> np.sum([[0, 1], [0, 5]], axis=1)

array([1, 5])

不使用numpy库的sum函数对二维list/array/matrix按行、列求和:

>>> s=array([[1, 2, 3], [0, 0, 1], [1, 0, 1], [0, 1, 0]])

>>> s

array([[1, 2, 3],

[0, 0, 1],

[1, 0, 1],

[0, 1, 0]])

>>> lin = map(sum,s)..........................在行方向上求和

>>> lin

[6, 1, 2, 1]

>>> col = map(sum,zip(*s))....................在列方向上求和

>>> col

[2, 3, 5]

可以看出:numpy确实方便好用

(6)np.multiply(x1, x2[, out])

多个参数的对应元素相乘,对于array来说,返回的就是对应元素相乘后的array,多于matrix,返回的就是对应元素相乘后的matrix

Parameters

x1, x2 : 类似于array,参与相乘的array.

Examples

>>>x=np.mat([[1,2,3],[2,3,4]])

>>>y=np.mat([[1,2,4],[2,1,1]])

>>>np.multiply(x,y)

matrix([[ 1,  4, 12],

[ 4,  3,  4]])

(7)np.dot(a, b, out=None)

对于一维的array,返回值是两个array的内积,等价于:sum([i*j for i,j in zip(a,b)])

对于二维array(包含matrix)来说,等价于矩阵相乘

(8)np.nonzero(a)

对于一维array来说,返回非零元素的索引

对于二维或多维的array来说,返回的是一个元组,元组的每个元素是array,每个array是a的非零元素的每一维取值

Parameters

a : 类似于array

Examples

>>> x = np.eye(3)

>>> x

array([[ 1., 0., 0.],

[ 0., 1., 0.],

[ 0., 0., 1.]])

>>> np.nonzero(x)

(array([0, 1, 2]), array([0, 1, 2]))表示非零元素有三个,第一个是第一行第一列的,第二个是第二行

a[nonzero(a)]得到了a中所有非零元素

>>>x[nonzero(x)]

 array([ 1.,  1.,  1.])

transpose(nonzero(a))返回一个二维数组,每个元素是a中非零元素的所有方向的维度

>>>np.transpose(np.nonzero(y))

array([[0, 0],

[1, 1],

[2, 2]], dtype=int64)

(9)np.insert(arr, obj, values, axis=None):

沿着给定的轴在给定的索引前插入相应的值

Paramaters:

arr : 类似于array

obj : 整数或者整数序列,是在值被插入之前定义索引的对象

values :类似于array,插入到arr里的值,如果值的类型不同于arr,那么会被转化为arr的类型,values会被重塑使得arr[...,obj,...] = values是合法的

axis : 整数,可选的,沿着这个轴插入values,如果是None,那么arr会首先被摊平

Examples:

>>>x = np.array([[1, 2, 2, 0, 1], [3, 4, 2, 0, 1], [2, 5, 1, 0, 2], [2, 3, 5, 1, 3], [1, 4, 2, 3, 1], [3, 4, 2, 2, 1]])

>>>x

array([[1, 2, 2, 0, 1],

[3, 4, 2, 0, 1],

[2, 5, 1, 0, 2],

[2, 3, 5, 1, 3],

[1, 4, 2, 3, 1],

[3, 4, 2, 2, 1]])

>>>x_theta0 = np.ones(x.shape[0])

>>>x_theta0

 array([ 1.,  1.,  1.,  1.,  1.,  1.])

>>>design_matrix = np.insert(x, 0, values=x_theta0, axis=1)

>>>design_matrix

array([[1, 1, 2, 2, 0, 1],

[1, 3, 4, 2, 0, 1],

[1, 2, 5, 1, 0, 2],

[1, 2, 3, 5, 1, 3],

[1, 1, 4, 2, 3, 1],

[1, 3, 4, 2, 2, 1]])

(10)np.random.randn(d0, d1, ..., dn)

从“标准正态”分布返回一个样本

Parameters

d0, d1, ..., dn :整数,可选的,是返回的array的各个维度的维数,都是正数,如果没有参数被给,那么会返回一个浮点数

Examples:

>>>np.random.randn(2, 1)

array([[-0.82557488],

[-1.5134927 ]])

3.array布尔切片

(1)一维切片

>>> x=np.random.rand(10)

>>> x

array([ 0.5993579 , 0.68693925, 0.74380945, 0.40993085, 0.72345401,0.64499497, 0.48715468, 0.80924589, 0.43362779, 0.06554248])

1)array与某个元素进行比较

>>> x>0.5 

array([ True, True, True, False, True, True, False, True, False, False], dtype=bool)

>>> x[x>0.5] #将它当做索引传回原数组,只获取那些>0.5的

array([ 0.5993579 , 0.68693925, 0.74380945, 0.72345401, 0.64499497,0.80924589])

2)两个array的对应位置元素作比较

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

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

>>> a>b

array([False, False, True], dtype=bool)

>>> a[a==b] #获取一样的元素

array([2])

3)all&any

>>> np.all(x<1) #测试x<1所返回的数组(传给all)中所有元素是否都等价True

True

>>> np.any([1,2,3,4]) #如果传入的数组中有至少一个元素等价True都返回True

True

(2)二维切片

>>>dataMatrix=np.matrix([[1., 2.1],

[2., 1.1],

[1.3, 1.],

[1., 1.],

[2., 1.]])

>>>retArray = np.ones((np.shape(dataMatrix)[0], 1))

>>>retArray

array([[ 1.],

[ 1.],

[ 1.],

[ 1.],

[ 1.]])

1)二维切片[i][j]

>>>dataMatrix[:, 0] <= 1.6 

matrix([[ True],

[False],

[ True],

[ True],

[False]], dtype=bool)

2)二维布尔切片

>>>retArray[dataMatrix[:, 0] <= 1.6] = -1.0

>>>retArray

array([[-1.],

[ 1.],

[-1.],

[-1.],

[ 1.]])

三.对比matrix和array

1.简述区别

Numpy matrices必须是2维的,但是numpy arrays (ndarrays) 可以是多维的(1D,2D,3D····ND).

Matrix是Array的一个小的分支,包含于Array。所以matrix 拥有array的所有特性。在numpy中matrix的主要优势是:相对简单的乘法运算符号

2.操作符运算

(1)array数组

numpy中最基本(默认)的类型是array,他的相关操作都是按元素操作的即用作数值计算当中(按元素操作有+,-,,/,*等)。

Examples:

import numpy as np

>>>np.array([1])+np.array([2])

array([3])

>>>np.array([1])-np.array([2])

array([-1])

>>>np.array([1])*np.array([2.0])

array([ 2.])

>>>np.array([1])/np.array([2])

array([0])

>>>np.array([1])/np.array([2.0])

array([ 0.5])

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

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

>>>x*y

array([ 3,  8, 15])

>>>np.multiply(x,y)

array([ 3,  8, 15])

>>>np.dot(x,y)

26

array的操作总结如下:

1.*和multiply:是两个array的对应元素的相乘

2.dot对于一维array是计算内积,对于多维是相当于矩阵相乘

3.**是array的对应元素做乘方

4.  .T表示转置

5. array转换为matrix:asmatrix()或者np.matrix()

6.多数numpy函数返回的是array类型,不是matrix类型

(2)matrix矩阵

    在numpy中的特殊类型,是作为array的子类出现,所以继承了array的所有特性并且有自己的特殊的地方,专门用来处理线性代数操作

Examples:

>>>x=np.matrix(x)

>>>y=np.matrix(y)

>>>x*y

Traceback (most recent call last):  File "C:\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2885, in run_code    exec(code_obj, self.user_global_ns, self.user_ns)  File "", line 1, inx*y

File "C:\Anaconda2\lib\site-packages\numpy\matrixlib\defmatrix.py", line 343, in __mul__

return N.dot(self, asmatrix(other))

ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)

matrix的操作总结如下:

1.*和dot表示是两个矩阵的相乘,满足矩阵相乘原则。

2.multiply表示两个matrix的对应元素的相乘

3.**是矩阵的乘方(power),和array的乘方不一样,不是单纯的每个元素做乘方,而是n个同样的矩阵相乘,当然前提矩阵能做乘方必须是方阵

4.除/则表示对于两个matrix的对应元素的相除

5.  .H,.A,.I表示共轭,转置,逆矩阵。

6.matrix转换为array用asarray()

(3)array和matrix的一个很难理解的点

     这里会涉及到rank的概念,在线性代数(math)rank表示秩,但是必须明确的是在numpy里rank不是表示秩的概念,是表示维数的概念

array要求秩为1(N*1,1*N等)或者大于2

matrix要求秩必须为2(rank必须为2)

下面通过例子来理解ndim和size:

>>> a#一维array

array([1, 2])

>>> a.size

2

>>> a.ndim

1

>>> b#二维array

array([[1, 2],

[2, 3]])

>>> b.size

4

>>> b.ndim

2

>>> c#small matrix

matrix([[1, 2, 3, 4],

[2, 3, 4, 5]])

>>> c.size

8

>>> c.ndim

2

>>> e#big matrix

matrix([[1, 2, 3, 4],

[2, 3, 4, 5],

[3, 4, 5, 6]])

>>>e.size

12

>>> e.ndim

2

总结:

1.ndim就是求的是rank,所以会发现matrix的都是2,但是array的就会存在差异,需要计算等。

2.size返回的是元素的个数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 来源:NumPy Tutorial - TutorialsPoint 译者:飞龙 协议:CC BY-NC-SA 4...
    布客飞龙阅读 32,720评论 6 96
  • 先决条件 在阅读这个教程之前,你多少需要知道点python。如果你想从新回忆下,请看看Python Tutoria...
    舒map阅读 2,570评论 1 13
  • NumPy是Python中关于科学计算的一个类库,在这里简单介绍一下。 来源:https://docs.scipy...
    灰太狼_black阅读 1,224评论 0 5
  • import numpy as np 创建ndarray data1 = [6,7.5, 8, 0, 1]arr1...
    陆文斌阅读 638评论 0 1
  • Numpy的组成与功能 Numpy(Numeric Python)可以被理解为一个用python实现的科学计算包,...
    不做大哥好多年阅读 4,276评论 0 10