赞
踩
Numpy是一个优秀的python第三方库,是Python生态系统中高性能科学计算和数据分析所需的基础软件包。它是几乎所有高级工具(如Pandas和scikit-learn)的基础。TensorFlow,PyTorch等大量机器学习框架的基础构建模块。
>>> import numpy as np
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
Ndarry是NumPy中一种N维数组对象
特点:
1. 它是以个N维数组,(1<=N)
2. 它被用来存放同类型的数据。
#所以说,它并不等同于元组(python无数组)
3. ndarray 中的每个元素在内存中都有相同存储大小的区域。
4. ndarray内部存在指向数据的指针。
#具有C语言的特色
5. 数据类型或 dtype(data-type),即数组元素的数据类型。
>>> import numpy as np
>>> a = np.array([1,2,3])
>>> a
array([1, 2, 3])
>>> print(a)
[1 2 3]
等价创建方法:
>>> b = (1,2,3)
>>> a = np.array(b)
>>> a
array([1, 2, 3])
**#b可以是一个列表;元组。甚至dict:**
>>> b = {"ss":123}
>>> a = np.array(b)
>>> a
array({'ss': 123}, dtype=object)
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
[4, 5, 6]])
#同样的方法我们还可以生成张量(多维数组)
示例代码:
>>> a = np.array([1, 2, 3], dtype = complex)
>>> print (a)
[1.+0.j 2.+0.j 3.+0.j]
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.size
9
#数值上应该等于 rows * columns
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.shape
(3, 3) # rows * columns
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.ndim
2
#没错,矩阵就是二维数组,不要犯糊涂
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
#int32是一种常见的数字类型,侧面证明array中元素的数据类型相同
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.itemsize
4
#这就类似C语言中的sizeof()
NumPy支持的数据类型:
很多。。。
常见的有:bool;int16/32/64;unit16/32/64(无符号数);float32/64;complex64/128
数据类型对象 (dtype)
数据类型对象用来描述与数组对应的内存区域如何使用。
从以下几个方面入手:
#比如在将字典转化成ndarray时dtype=object >>> b = {"ss":123} >>> a = np.array(b) >>> a array({'ss': 123}, dtype=object) #数据类型是可以转化的 >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> a.dtype dtype('int32') >>> a.dtype = 'float32' >>> a array([[1.4e-45, 2.8e-45, 4.2e-45], [5.6e-45, 7.0e-45, 8.4e-45], [9.8e-45, 1.1e-44, 1.3e-44]], dtype=float32) #同时又不能随意的转化 >>> a = np.array(b) >>> a array({'ss': 123}, dtype=object) >>> a.dtype dtype('O') #数据类型时Object >>> a.dtype = 'int32' Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python36\lib\site-packages\numpy\core\_internal.py", line 494, in _view_is_safe raise TypeError("Cannot change data-type for object array.") TypeError: Cannot change data-type for object array.
#数据的大小同样可变,但是可能会得到不可测的结果
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
>>> a.dtype = 'int16'
>>> a
array([[1, 0, 2, 0, 3, 0],
[4, 0, 5, 0, 6, 0],
[7, 0, 8, 0, 9, 0]], dtype=int16)
#数据类型同样不能随便变化,比如不能让他凭空的将精度变高
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a.dtype
dtype('int32')
>>> a.dtype = 'int64'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.
在这里插入代码片
//创建向量
>>> np.ones(5)
array([1., 1., 1., 1., 1.])
//创建矩阵
>>> a = np.ones([3,3])
>>> a
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
//做一些改动
>>> a =3*np.ones([3,3])
>>> a
array([[3., 3., 3.],
[3., 3., 3.],
[3., 3., 3.]])
//创建向量
>>> np.zeros(5)
array([0., 0., 0., 0., 0.])
//创建矩阵
>>> a = np.zeros([3,3])
>>> a
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
//再次操作
>>> a =3* np.zeros([3,3])
>>> a
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
//默认生成的随机数的范围是0~1
>>> np.random.rand(3,3)
array([[3.29636146e-02, 4.90232936e-01, 3.40464701e-01],
[3.94844706e-01, 4.80900614e-02, 2.06383792e-04],
[9.43723782e-01, 8.83631432e-01, 2.90263091e-01]])
//做一些改动,改变随机数的范围.使之范围在1~10
>>> np.random.rand(3,3)*10
array([[4.76591306, 3.44215456, 5.66092258],
[3.58430809, 9.85651945, 9.12340062],
[2.47789989, 2.69133064, 4.49325786]])
>>> np.random.uniform(10,20)
13.740520696927998
>>> np.random.randint(10,20)
15
//上代码
>>> b = (1,2,3)
// array方法
>>> c=np.array(b)
>>> c
array([1, 2, 3])
// asarray方法
>>> d = np.asarray(b)
>>> d
array([1, 2, 3])
从上面代码看不出什么区别,这也就体现了他们共同的功能:array和asarray都可将结构数据转换为ndarray类型。
//上代码
>>> type(b)
<class 'tuple'>
>>> type(c)
<class 'numpy.ndarray'>
>>> type(d)
<class 'numpy.ndarray'>
它们真正的区别在于但是主要区别就是当数据源是ndarray时,
array仍会copy出一个副本,占用新的内存,但asarray不会。
//上代码 >>> a = (1,2,3) >>> b = np.array(a) >>> c = np.array(b) //array实现copy功能 >>> c[0] = 3 >>> c array([3, 2, 3]) >>> b array([1, 2, 3]) //同样的操作对ndarray来一遍 >>> a = (1,2,3) >>> b = np.asarray(a) >>> c = np.asarray(b) //asarray同样能够实现copy功能 >>> b[0]=3 >>> b array([3, 2, 3]) >>> c array([3, 2, 3])
>>> np.random.normal(10,4,(3,3))
array([[12.34628758, 6.50655525, 5.56074923],
[20.07590444, 2.31052866, 10.51850977],
[ 2.27598256, 7.61946729, 6.61567373]])
//标准差就是方差再开根号。。
>>> np.arange(10,20,2)
array([10, 12, 14, 16, 18])
//可以看出ndarray类型像python列表,事实上它也确实可以像列表一样索引
//如果不给出第三个参数,那么默认是50 >>> np.linspace(1,10) array([ 1. , 1.18367347, 1.36734694, 1.55102041, 1.73469388, 1.91836735, 2.10204082, 2.28571429, 2.46938776, 2.65306122, 2.83673469, 3.02040816, 3.20408163, 3.3877551 , 3.57142857, 3.75510204, 3.93877551, 4.12244898, 4.30612245, 4.48979592, 4.67346939, 4.85714286, 5.04081633, 5.2244898 , 5.40816327, 5.59183673, 5.7755102 , 5.95918367, 6.14285714, 6.32653061, 6.51020408, 6.69387755, 6.87755102, 7.06122449, 7.24489796, 7.42857143, 7.6122449 , 7.79591837, 7.97959184, 8.16326531, 8.34693878, 8.53061224, 8.71428571, 8.89795918, 9.08163265, 9.26530612, 9.44897959, 9.63265306, 9.81632653, 10. ]) >>> np.linspace(1,10,10) array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]) //也可以皮一下 >>> np.linspace(1,1,10) array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) //对于这里面的 1. , 2. ,3. 不要太纠结,他们实际上就是1.0,2.0,3.0 //上代码 >>> a = (1.,2.,3.) >>> a (1.0, 2.0, 3.0)
//同样的默认生成50个元素 >>> np.logspace(1,2) array([ 10. , 10.48113134, 10.98541142, 11.51395399, 12.06792641, 12.64855217, 13.25711366, 13.89495494, 14.56348478, 15.26417967, 15.9985872 , 16.76832937, 17.57510625, 18.42069969, 19.30697729, 20.23589648, 21.20950888, 22.22996483, 23.29951811, 24.42053095, 25.59547923, 26.82695795, 28.11768698, 29.47051703, 30.88843596, 32.37457543, 33.93221772, 35.56480306, 37.2759372 , 39.06939937, 40.94915062, 42.9193426 , 44.98432669, 47.14866363, 49.41713361, 51.79474679, 54.28675439, 56.89866029, 59.63623317, 62.50551925, 65.51285569, 68.6648845 , 71.9685673 , 75.43120063, 79.06043211, 82.86427729, 86.85113738, 91.0298178 , 95.40954763, 100. ]) //生成10个 >>> np.logspace(1,2,10) **或者** np.logspace(1,2,num = 10) array([ 10. , 12.91549665, 16.68100537, 21.5443469 , 27.82559402, 35.93813664, 46.41588834, 59.94842503, 77.42636827, 100. ]) //以2为底数 >>> np.logspace(1,2,10,base=2) array([2. , 2.16011948, 2.33305808, 2.5198421 , 2.72158 , 2.93946898, 3.1748021 , 3.42897593, 3.70349885, 4. ])
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,但是列表生成式是更好的方法。
对向量使用切片和索引
>>> a = np.arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> b = slice(2,9,2) >>> b slice(2, 9, 2) >>> a[b] array([2, 4, 6, 8]) //b只是切片本身,只有和ndarray结合起来才具有意义 //我们还可以使用**列表生成式**的方式生成切片 >>> c = a[2,9,2] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: too many indices for array >>> c = a[2:9:2] >>> c array([2, 4, 6, 8]) //冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。 如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。 // a[2:9:2] == a[slice(2,9,2)] 不恰当的说:**[2:9:2] == slice(2,8,2)** //所以说直接用列表生成式的方法比较好
>>> a = np.random.normal(10,4,(4,5)) >>> a array([[ 3.05513778, 10.70987312, 5.67037114, 8.08392751, 5.92022034], [11.99962594, 8.60524009, 9.87238926, 13.02399218, 9.11991441], [16.45312757, 10.63062961, 6.71416586, 18.65010408, 10.90224202], [17.77987518, 9.43236602, 8.63643317, 8.31419578, 11.0124451 ]]) >>> b = a[1:3, 2:4] //**截取2~3行,3~4列的数据(索引从0开始)** >>> b array([[ 9.87238926, 13.02399218], [ 6.71416586, 18.65010408]]) //实际上,多维数组的操作可以简化成这样 **a[操作1,操作2,操作3,···]** 操作1是针对第一秩(行)的操作;操作2 是针对第二秩(列)的操作;并以此类推···· 可见逗号是分割对不同维度操作的间隔符 //上代码 >>> a = np.random.rand(3,4) >>> a array([[0.64359865, 0.78614581, 0.60116405, 0.49593726], [0.74587207, 0.02149204, 0.66179379, 0.11995186], [0.80315084, 0.36740358, 0.36714436, 0.77535863]]) >>> a[0,] //取第一行的元素 array([0.64359865, 0.78614581, 0.60116405, 0.49593726]) >>> a[0,...] //取第一行的元素 array([0.64359865, 0.78614581, 0.60116405, 0.49593726]) >>> a[,0] File "<stdin>", line 1 a[,0] ^ SyntaxError: invalid syntax //此处报错了,所以说...还是很有必要的 >>> a[...,0] //取第一列的元素 array([0.64359865, 0.74587207, 0.80315084]) >>> a[...,0:] //取第一列及其之后所有列的元素 array([[0.64359865, 0.78614581, 0.60116405, 0.49593726], [0.74587207, 0.02149204, 0.66179379, 0.11995186], [0.80315084, 0.36740358, 0.36714436, 0.77535863]]) >>> a[...,3:] array([[0.49593726], [0.11995186], [0.77535863]])
//以下实例获取数组中(0,0),(1,1)和(2,0)位置处的元素
>>> x = np.array([[1, 2], [3, 4], [5, 6]])
>>> y = x[[0,1,2], [0,1,0]]
>>> y
array([1, 4, 5])
//布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。可以看作 是一个**过滤器** //上代码 >>> a array([[0.64359865, 0.78614581, 0.60116405, 0.49593726], [0.74587207, 0.02149204, 0.66179379, 0.11995186], [0.80315084, 0.36740358, 0.36714436, 0.77535863]]) >>> a[a>0.5] array([0.64359865, 0.78614581, 0.60116405, 0.74587207, 0.66179379, 0.80315084, 0.77535863]) //最终得到得到的结果是一个向量 //下列代码可以从数组中过滤掉非复数元素。 >>> a = np.array([1, 2+6j, 5, 3.5+5j]) >>> a[np.iscomplex(a)] array([2. +6.j, 3.5+5.j])
>>> np.ones(12)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> a = np.ones(12)
>>> a.reshape(3,4)
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
//综合使用
>>> a = np.ones(12).reshape(3,4)
>>> a
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
广播的规则:
迭代器最基本的任务的可以完成对数组元素的访问。
//上代码 >>> a = np.arange(6).reshape(2,3) >>> a array([[0, 1, 2], [3, 4, 5]]) >>> for i in np.nditer(a): ... print(i+',') File "<stdin>", line 2 print(i+',') ^ IndentationError: expected an indented block //在命令行模式下回车不自动缩进! >>> for i in np.nditer(a): ... print (i+',' ) ... Traceback (most recent call last): File "<stdin>", line 2, in <module> numpy.core._exceptions.UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('<U11'), dtype('<U11')) -> dtype('<U11') //此处的**i**已经不是普通的字符型了,不能够简单的与字符进行拼接 >>> for i in np.nditer(a): ... print(i,end=',') ... 0,1,2,3,4,5,>>> >>>
//上代码
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> for i in np.nditer(a,order = 'C'): //很显然这是按照行序进行迭代
... print(i,end=',')
...
0,1,2,3,4,5,>>>
>>> for i in np.nditer(a,order = 'F'): //这是按照列序进行迭代
... print(i,end=',')
...
0,3,1,4,2,5,>>>
>>>
//上代码 >>> a array([[0, 1, 2], [3, 4, 5]]) >>> a.T array([[0, 3], [1, 4], [2, 5]]) >>> for i in np.nditer(a): ... print(i,end=',') ... 0,1,2,3,4,5,>>> >>> for i in np.nditer(a.T): ... print(i,end=',') ... 0,1,2,3,4,5,>>> //我们发现,矩阵转置之后再进行迭代顺序并没有发生改变,事实上,在内存中它们的存储顺序的确一样,选择 的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是**行序优先**(row-major order,或 者说是 C-order)。 >>> for i in np.nditer(a,order = 'F'): ... print(i,end=',') ... 0,3,1,4,2,5,>>> //按照列进行迭代就使得迭代的方式发生了改变
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。