本篇内容主要讲解“Numpy的基本用法整理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Numpy的基本用法整理”吧!
前言
Numpy是一个开源的Python科学计算库,它是python科学计算库的基础库,许多其他著名的科学计算库如Pandas,Scikit-learn等都要用到Numpy库的一些功能。
本文主要内容如下:
Numpy数组对象
创建ndarray数组
Numpy的数值类型
ndarray数组的属性
ndarray数组的切片和索引
处理数组形状
数组的类型转换
numpy常用统计函数
数组的广播
1 Numpy数组对象
Numpy中的多维数组称为ndarray,这是Numpy中最常见的数组对象。ndarray对象通常包含两个部分:
ndarray数据本身
描述数据的元数据
Numpy数组的优势
Numpy数组通常是由相同种类的元素组成的,即数组中的数据项的类型一致。这样有一个好处,由于知道数组元素的类型相同,所以能快速确定存储数据所需空间的大小。
Numpy数组能够运用向量化运算来处理整个数组,速度较快;而Python的列表则通常需要借助循环语句遍历列表,运行效率相对来说要差。
Numpy使用了优化过的C API,运算速度较快
关于向量化和标量化运算,对比下面的参考例子就可以看出差异
使用python的list进行循环遍历运算
1. def pySum():
2. a = list(range(10000))
3. b = list(range(10000))
4. c = []
5. for i in range(len(a)):
6. c.append(a[i]**2 + b[i]**2)
7.
8. return c
1. %timeit pySum()
1. 10 loops, best of 3: 49.4 ms per loop
使用numpy进行向量化运算
1. import numpy as np
2. def npSum():
3. a = np.arange(10000)
4. b = np.arange(10000)
5. c = a**2 + b**2
6. return c
1. %timeit npSum()
1. The slowest run took 262.56 times longer than the fastest. This could mean that an intermediate result is being cached.
2. 1000 loops, best of 3: 128 ?s per loop
从上面的运行结果可以看出,numpy的向量化运算的效率要远远高于python的循环遍历运算(效率相差好几百倍)。 (1ms=1000?s)
2 创建ndarray数组
首先需要导入numpy库,在导入numpy库时通常使用“np”作为简写,这也是Numpy官方倡导的写法。
当然,你也可以选择其他简写的方式或者直接写numpy,但还是建议用“np”,这样你的程序能和大都数人的程序保持一致。
1. import numpy as np
创建ndarray数组的方式有很多种,这里介绍我使用的较多的几种:
Method 1: 基于list或tuple
1. # 一维数组
2.
3. # 基于list
4. arr1 = np.array([1,2,3,4])
5. print(arr1)
6.
7. # 基于tuple
8. arr_tuple = np.array((1,2,3,4))
9. print(arr_tuple)
10.
11. # 二维数组 (2*3)
12. arr2 = np.array([[1,2,4], [3,4,5]])
13. arr2
1. [1 2 3 4]
2. [1 2 3 4]
3. array([[1, 2, 4],
4. [3, 4, 5]])
请注意:
一维数组用print输出的时候为 [1 2 3 4],跟python的列表是有些差异的,没有“,”
在创建二维数组时,在每个子list外面还有一个"[]",形式为“[[list1], [list2]]”
Method 2: 基于np.arange
1. # 一维数组
2. arr1 = np.arange(5)
3. print(arr1)
4.
5. # 二维数组
6. arr2 = np.array([np.arange(3), np.arange(3)])
7. arr2
1. [0 1 2 3 4]
2. array([[0, 1, 2],
3. [0, 1, 2]])
Method 3: 基于arange以及reshape创建多维数组
1. # 创建三维数组
2. arr = np.arange(24).reshape(2,3,4)
3. arr
1. array([[[ 0, 1, 2, 3],
2. [ 4, 5, 6, 7],
3. [ 8, 9, 10, 11]],
4.
5. [[12, 13, 14, 15],
6. [16, 17, 18, 19],
7. [20, 21, 22, 23]]])
请注意:arange的长度与ndarray的维度的乘积要相等,即 24 = 2X3X4
用numpy.random创建数组的方法,可以参考下面的文章
为什么你用不好Numpy的random函数?
其他创建ndarray的方法,各位小伙伴们自己可以研究下。
3 Numpy的数值类型
Numpy的数值类型如下:
每一种数据类型都有相应的数据转换函数,参考示例如下:
1. np.int8(12.334)
1. 12
1. np.float64(12)
1. 12.0
1. np.float(True)
1. 1.0
1. bool(1)
1. True
在创建ndarray数组时,可以指定数值类型:
1. a = np.arange(5, dtype=float)
2. a
1. array([ 0., 1., 2., 3., 4.])
请注意,复数不能转换成为整数类型或者浮点数,比如下面的代码会运行出错
1. # float(42 + 1j)
4 ndarray数组的属性
dtype属性,ndarray数组的数据类型,数据类型的种类,前面已描述。
1. np.arange(4, dtype=float)
1. array([ 0., 1., 2., 3.])
1. # 'D'表示复数类型
2. np.arange(4, dtype='D')
1. array([ 0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j])
1. np.array([1.22,3.45,6.779], dtype='int8')
1. array([1, 3, 6], dtype=int8)
ndim属性,数组维度的数量
1. a = np.array([[1,2,3], [7,8,9]])
2. a.ndim
1. 2
shape属性,数组对象的尺度,对于矩阵,即n行m列,shape是一个元组(tuple)
1. a.shape
1. (2, 3)
size属性用来保存元素的数量,相当于shape中nXm的值
1. a.size
1. 6
itemsize属性返回数组中各个元素所占用的字节数大小。
1. a.itemsize
1. 4
nbytes属性,如果想知道整个数组所需的字节数量,可以使用nbytes属性。其值等于数组的size属性值乘以itemsize属性值。
1. a.nbytes
1. 24
1. a.size*a.itemsize
1. 24
T属性,数组转置
1. b = np.arange(24).reshape(4,6)
2. b
1. array([[ 0, 1, 2, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11],
3. [12, 13, 14, 15, 16, 17],
4. [18, 19, 20, 21, 22, 23]])
1. b.T
1. array([[ 0, 6, 12, 18],
2. [ 1, 7, 13, 19],
3. [ 2, 8, 14, 20],
4. [ 3, 9, 15, 21],
5. [ 4, 10, 16, 22],
6. [ 5, 11, 17, 23]])
复数的实部和虚部属性,real和imag属性
1. d = np.array([1.2+2j, 2+3j])
2. d
1. array([ 1.2+2.j, 2.0+3.j])
real属性返回数组的实部
1. d.real
1. array([ 1.2, 2. ])
imag属性返回数组的虚部
1. d.imag
1. array([ 2., 3.])
flat属性,返回一个numpy.flatiter对象,即可迭代的对象。
1. e = np.arange(6).reshape(2,3)
2. e
1. array([[0, 1, 2],
2. [3, 4, 5]])
1. f = e.flat
2. f
1. <numpy.flatiter at 0x65eaca0>
1. for item in f:
2. print(item)
1. 0
2. 1
3. 2
4. 3
5. 4
6. 5
可通过位置进行索引,如下:
1. f[2]
1. 2
1. f[[1,4]]
1. array([1, 4])
也可以进行赋值
1. e.flat=7
2. e
1. array([[7, 7, 7],
2. [7, 7, 7]])
1. e.flat[[1,4]]=1
2. e
1. array([[7, 1, 7],
2. [7, 1, 7]])
下图是对ndarray各种属性的一个小结
5 ndarray数组的切片和索引
一维数组
一维数组的切片和索引与python的list索引类似。
1. a = np.arange(7)
2. a
1. array([0, 1, 2, 3, 4, 5, 6])
1. a[1:4]
1. array([1, 2, 3])
1. # 每间隔2个取一个数
2. a[ : 6: 2]
1. array([0, 2, 4])
二维数组的切片和索引,如下所示:
插播一条硬广:技术文章转发太多。本文涉及的代码量比较多,如需要查看源代码,请在微信公众号“Python数据之道”(ID:PyDataRoad)后台回复关键字“2017026”。
6 处理数组形状
6.1 形状转换
reshape()和resize()
1. b.reshape(4,3)
1. array([[ 0, 1, 2],
2. [ 3, 4, 5],
3. [ 6, 7, 8],
4. [ 9, 10, 11]])
1. b
1. array([[ 0, 1, 2, 3],
2. [ 4, 5, 6, 7],
3. [ 8, 9, 10, 11]])
1. b.resize(4,3)
2. b
1. array([[ 0, 1, 2],
2. [ 3, 4, 5],
3. [ 6, 7, 8],
4. [ 9, 10, 11]])
函数resize()的作用跟reshape()类似,但是会改变所作用的数组,相当于有inplace=True的效果
ravel()和flatten(),将多维数组转换成一维数组,如下:
1. b.ravel()
1. array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
1. b.flatten()
1. array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
1. b
1. array([[ 0, 1, 2],
2. [ 3, 4, 5],
3. [ 6, 7, 8],
4. [ 9, 10, 11]])
两者的区别在于返回拷贝(copy)还是返回视图(view),flatten()返回一份拷贝,需要分配新的内存空间,对拷贝所做的修改不会影响原始矩阵,而ravel()返回的是视图(view),会影响原始矩阵。
参考如下代码:
用tuple指定数组的形状,如下:
1. b.shape=(2,6)
2. b
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11]])
转置
前面描述了数组转置的属性(T),也可以通过transpose()函数来实现
1. b.transpose()
1. array([[ 0, 6],
2. [ 1, 7],
3. [20, 8],
4. [ 3, 9],
5. [ 4, 10],
6. [ 5, 11]])
6.2 堆叠数组
1. b
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11]])
1. c = b*2
2. c
1. array([[ 0, 2, 40, 6, 8, 10],
2. [12, 14, 16, 18, 20, 22]])
水平叠加
hstack()
1. np.hstack((b,c))
1. array([[ 0, 1, 20, 3, 4, 5, 0, 2, 40, 6, 8, 10],
2. [ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22]])
column_stack()函数以列方式对数组进行叠加,功能类似hstack()
1. np.column_stack((b,c))
1. array([[ 0, 1, 20, 3, 4, 5, 0, 2, 40, 6, 8, 10],
2. [ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22]])
垂直叠加
vstack()
1. np.vstack((b,c))
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11],
3. [ 0, 2, 40, 6, 8, 10],
4. [12, 14, 16, 18, 20, 22]])
row_stack()函数以行方式对数组进行叠加,功能类似vstack()
1. np.row_stack((b,c))
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11],
3. [ 0, 2, 40, 6, 8, 10],
4. [12, 14, 16, 18, 20, 22]])
concatenate()方法,通过设置axis的值来设置叠加方向
axis=1时,沿水平方向叠加
axis=0时,沿垂直方向叠加
1. np.concatenate((b,c),axis=1)
1. array([[ 0, 1, 20, 3, 4, 5, 0, 2, 40, 6, 8, 10],
2. [ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22]])
1. np.concatenate((b,c),axis=0)
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11],
3. [ 0, 2, 40, 6, 8, 10],
4. [12, 14, 16, 18, 20, 22]])
由于针对数组的轴为0或1的方向经常会混淆,通过示意图,或许可以更好的理解。
关于数组的轴方向示意图,以及叠加的示意图,如下:
深度叠加
这个有点烧脑,举个例子如下,自己可以体会下:
1. arr_dstack = np.dstack((b,c))
2. print(arr_dstack.shape)
3. arr_dstack
1. (2, 6, 2)
2.
3. array([[[ 0, 0],
4. [ 1, 2],
5. [20, 40],
6. [ 3, 6],
7. [ 4, 8],
8. [ 5, 10]],
9.
10. [[ 6, 12],
11. [ 7, 14],
12. [ 8, 16],
13. [ 9, 18],
14. [10, 20],
15. [11, 22]]])
叠加前,b和c均是shape为(2,6)的二维数组,叠加后,arr_dstack是shape为(2,6,2)的三维数组。
深度叠加的示意图如下:
6.3 数组的拆分
跟数组的叠加类似,数组的拆分可以分为横向拆分、纵向拆分以及深度拆分。
涉及的函数为 hsplit()、vsplit()、dsplit() 以及split()
1. b
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11]])
沿横向轴拆分(axis=1)
1. np.hsplit(b, 2)
1. [array([[ 0, 1, 20],
2. [ 6, 7, 8]]), array([[ 3, 4, 5],
3. [ 9, 10, 11]])]
1. np.split(b,2, axis=1)
1. [array([[ 0, 1, 20],
2. [ 6, 7, 8]]), array([[ 3, 4, 5],
3. [ 9, 10, 11]])]
沿纵向轴拆分(axis=0)
1. np.vsplit(b, 2)
1. [array([[ 0, 1, 20, 3, 4, 5]]), array([[ 6, 7, 8, 9, 10, 11]])]
1. np.split(b,2,axis=0)
1. [array([[ 0, 1, 20, 3, 4, 5]]), array([[ 6, 7, 8, 9, 10, 11]])]
深度拆分
1. arr_dstack
1. array([[[ 0, 0],
2. [ 1, 2],
3. [20, 40],
4. [ 3, 6],
5. [ 4, 8],
6. [ 5, 10]],
7.
8. [[ 6, 12],
9. [ 7, 14],
10. [ 8, 16],
11. [ 9, 18],
12. [10, 20],
13. [11, 22]]])
1. np.dsplit(arr_dstack,2)
1. [array([[[ 0],
2. [ 1],
3. [20],
4. [ 3],
5. [ 4],
6. [ 5]],
7.
8. [[ 6],
9. [ 7],
10. [ 8],
11. [ 9],
12. [10],
13. [11]]]), array([[[ 0],
14. [ 2],
15. [40],
16. [ 6],
17. [ 8],
18. [10]],
19.
20. [[12],
21. [14],
22. [16],
23. [18],
24. [20],
25. [22]]])]
拆分的结果是原来的三维数组拆分成为两个二维数组。
这个烧脑的拆分过程可以自行分析下~~
7 数组的类型转换
数组转换成list,使用tolist()
1. b
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11]])
1. b.tolist()
1. [[0, 1, 20, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
转换成指定类型,astype()函数
1. b.astype(float)
1. array([[ 0., 1., 20., 3., 4., 5.],
2. [ 6., 7., 8., 9., 10., 11.]])
8 numpy常用统计函数
常用的函数如下:
请注意函数在使用时需要指定axis轴的方向,若不指定,默认统计整个数组。
np.sum(),返回求和
np.mean(),返回均值
np.max(),返回最大值
np.min(),返回最小值
np.ptp(),数组沿指定轴返回最大值减去最小值,即(max-min)
np.std(),返回标准偏差(standard deviation)
np.var(),返回方差(variance)
np.cumsum(),返回累加值
np.cumprod(),返回累乘积值
1. b
1. array([[ 0, 1, 20, 3, 4, 5],
2. [ 6, 7, 8, 9, 10, 11]])
1. np.max(b)
1. 20
1. # 沿axis=1轴方向统计
2. np.max(b,axis=1)
1. array([20, 11])
1. # 沿axis=0轴方向统计
2. np.max(b,axis=0)
1. array([ 6, 7, 20, 9, 10, 11])
1. np.min(b)
1. 0
np.ptp(),返回整个数组的最大值减去最小值,如下:
1. np.ptp(b)
1. 20
1. # 沿axis=0轴方向
2. np.ptp(b, axis=0)
1. array([ 6, 6, 12, 6, 6, 6])
1. # 沿axis=1轴方向
2. np.ptp(b, axis=1)
1. array([20, 5])
np.cumsum(),沿指定轴方向进行累加
1. b.resize(4,3)
2. b
1. array([[ 0, 1, 20],
2. [ 3, 4, 5],
3. [ 6, 7, 8],
4. [ 9, 10, 11]])
1. np.cumsum(b, axis=1)
1. array([[ 0, 1, 21],
2. [ 3, 7, 12],
3. [ 6, 13, 21],
4. [ 9, 19, 30]], dtype=int32)
1. np.cumsum(b, axis=0)
1. array([[ 0, 1, 20],
2. [ 3, 5, 25],
3. [ 9, 12, 33],
4. [18, 22, 44]], dtype=int32)
np.cumprod(),沿指定轴方向进行累乘积 (Return the cumulative product of the elements along the given axis)
1. np.cumprod(b,axis=1)
1. array([[ 0, 0, 0],
2. [ 3, 12, 60],
3. [ 6, 42, 336],
4. [ 9, 90, 990]], dtype=int32)
1. np.cumprod(b,axis=0)
1. array([[ 0, 1, 20],
2. [ 0, 4, 100],
3. [ 0, 28, 800],
4. [ 0, 280, 8800]], dtype=int32)
9 数组的广播
当数组跟一个标量进行数学运算时,标量需要根据数组的形状进行扩展,然后执行运算。
这个扩展的过程称为“广播(broadcasting)”
1. b
1. array([[ 0, 1, 20],
2. [ 3, 4, 5],
3. [ 6, 7, 8],
4. [ 9, 10, 11]])
1. d = b + 2
2. d
1. array([[ 2, 3, 22],
2. [ 5, 6, 7],
3. [ 8, 9, 10],
4. [11, 12, 13]])
写在最后
numpy涵盖的内容其实是非常丰富的,本文仅仅介绍了numpy一些常用的基本功能,算是对numpy的一个入门级的简单的较为全面的描述。
numpy官方的《Numpy Reference》文档,光页面数量就有1500+页,如想要系统的学习numpy,建议仔细阅读官方的参考文档,可在其官方网站进行查阅。当然,资料都是英文版的,可能看起来难度稍微大点,看习惯了就好。
到此,相信大家对“Numpy的基本用法整理”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。