数据处理必修库Numpy
数据处理必修库Numpy
来源:蝈蝈大数据工作坊http://www.ggbigdata.cn
python的编辑器五花八门,眼花缭乱,对于新手来说,最好的就是Anaconda。
如果你已经安装了Anaconda,那么你就已经安装了NumPy,不仅如此,很多常用的库Anaconda都替你安装好了,如pandas,这就省去了自行安装的麻烦!
Python的标准发行版或任何其他发行版,可以访问官网获取信息http://www.numpy.org。
【编者注:蝈蝈强烈推荐使用Anaconda,并且在做交流时、教师教学时也建议使用Anaconda下的Jupyter Notebook,交流中对方可以实时地看到代码的执行过程,对于学生还可以将上课的内容导出为html网页格式,供同学们课下复习,以对课堂知识的内容再现。很多老师害怕课堂代码出问题,不敢使用实时代码运行,而使用ppt教学,其实效果并不好。】
■ 01 导入NumPy
一旦启动了一个新的IPython(spyder)或者Jupyter(notebook)会话,就可以导入Numpy模块并按照以下步骤来验证版本:
import numpy
numpy.version
输出结果:
1.15.4
提示:在Jupyter Notebook中,键入代码后,可以按下Ctrl+Enter,以执行一个单元格。或者,按下Shift+Enter以执行单元格,并自动插入或者选择该单元格下面的单元格。在菜单栏上单击Help | Keyboard Shortcut以检查所有的键盘快捷键,或者依次单击Help | User Interface Tour以进行快速浏览。
此处讨论的部分包,建议使用NumPy 1.8版本或后续更高级的版本。按照惯例,在Python领域中,导入NumPy都会使用np作为别名:
import numpy as np
np.version
输出结果:
1.15.4
■ 02 理解NumPy数组
Python语言的变量类型不必指定,无论何时创建一个新变量,都会自动识别其类型。例如,下面的内容将自动表示为一个整数:
a = 5
输入下面type函数可以得到变量的类型:
type(a)
输出结果:
int
range (x)函数将创建从0到x–1的所有整数,即整数范围是左闭右开[0,x),但这些整数形象地说是存储在容器里,是散乱的,当你需要它时,你可对他进行调取,如你需要调用它为一个列表,那就是用list来调用,当需要调用它当作元组时,就是用tuple来调用它。如
i_list=list(range(10))
i_list
输出结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
类似地,我们通过让Python遍历整数列表i_list中的所有元素,并对每个元素应用str()函数(该函数将一个数转换成一个字符串),来创建一个字符串列表:
str_list = [str(i) for i in i_list]
str_list
输出结果:
[‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’]
可是,用列表进行数学运算并不是很灵活。例如,我们想要将i_list中的每个元素都乘以一个因子2。执行以下操作可能是一种简单的方法,看看输出结果是怎样的:
i_list * 2
输出结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
其结果是将i_list自身“长度”变长了一倍,变长的部分是把原来的元素复制过来了,这并不是我们想要的!
这就是NumPy的用武之地。NumPy是专为简化Python中的数组运算而设计的。我们可以快速将整数列表转换为一个NumPy数组:
import numpy as np
i_arr = np.array(i_list)
i_arr
输出结果:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
让我们试着将数组乘以2会怎样:
i_arr*2
输出结果:
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
这次是我们要的结果!加法、减法、除法以及很多其他运算也是同样的。
而且,每个NumPy数组都具有以下属性:
ndim:维数。
shape:每一维的大小。
size:数组中元素的总数。
dtype:数组的数据类型(例如int、float、string等)。
让我们来看看整数数组的上述属性:
print("i_arr ndim: ", i_arr.ndim)
print("i_arr shape: ", i_arr.shape)
print("i_arr size: ", i_arr.size)
print("i_arr dtype: ", i_arr.dtype)
输出结果:
i_arr ndim: 1
i_arr shape: (10,)
i_arr size: 10
i_arr dtype: int32
从这些输出中,我们可以看到数组只包含一维,其包含10个元素且所有元素都是64位的整数。当然,如果你在32位机器上执行这段代码,你可能会得到dtype:int 32。
■ 03 通过索引访问单个数组元素
在一维数组中,通过在方括号中指定所需的索引,可以访问第i个值(从0开始计算),与list一样:
i_arr
输出结果:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
再看:
int_arr[0]
输出结果:
0
再来一次:
int_arr[0]
输出结果:
3
要从数组的末尾建立索引,可以使用负索引号:
int_arr[-1]
输出结果:
9
再如
int_arr[-3]
输出结果:
7
数组也可以有类似于list的切片操作,如下所示:
i_arr[2:5]
输出结果:
array([2, 3, 4])
还可以有步长
i_arr[0:8:2]
输出结果:
array([0, 2, 4, 6])
提示:NumPy中数组切片的一般形式与list中的相同。使用x [start: stop: step]访问数组x中的一个片段。
■ 04 创建多维数组
数组不必局限于列表。实际上,数组可以有任意维数。在机器学习中,通常我们至少要处理二维数组,列索引表示特定的特征值,行包含实际的特征值。
使用NumPy可以轻松地创建多维数组。假设我们想要创建一个3行5列的数组,所有的元素都初始化为0。如果我们不指定数据类型,NumPy将默认使用float类型:
arr_2d=np.zeros((3,5))
arr_2d
输出结果:
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
在OpenCV中:这可以解释为所有像素设置为0(黑色)的一个3×5的灰度图像。例如,如果想要创建具有3个颜色通道(R、G和B)2×4像素的一个小图像,所有像素都设置为白色,我们可以使用NumPy创建一个3×2×4的三维数组:
aa3=np.zeros((3,2,4))
aa3
输出结果:
array([[[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
这里,第一维定义颜色通道(OpenCV中的蓝色、绿色和红色)。因此,如果这是真实的图像数据,我们可以通过数组切片轻松地获得第一个通道中的颜色信息:
aa3[0,:,:]
输出结果:
array([[0., 0., 0., 0.],
[0., 0., 0., 0.]])
在OpenCV中,图像要么是值在0到1之间的32位浮点数组,要么是值在0到255之间的8位整数数组。因此,使用8位整数,通过指定NumPy的dtype属性并将数组中的所有1乘以255,我们还可以创建一个2×4像素、全为白色的RGB图像:
arr_3d=np.ones((3,2,4),dtype=np.uint8)*255
arr_3d
输出结果:
array([[[255, 255, 255, 255],
[255, 255, 255, 255]],
[[255, 255, 255, 255],
[255, 255, 255, 255]],
[[255, 255, 255, 255],
[255, 255, 255, 255]]], dtype=uint8)
■ 05 修改数组的维度
我们也可以修改数组的“形状”。如上面的aa3的形状是(3,2,4),下面将其修改为(4,6)(4行6列)
aa3.reshape(4,6)
结果为:
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
aa3.reshape(4,6)也可以写成aa3.reshape(4,-1)或者aa3.reshape(-1,6),这里的-1表示不需要计算,如(4,-1)表示形状改变为4行,至于多少列计算机自动计算;(-1,6)表示修改为6列,至于多少行计算机自动计算去,当然这里要能够分成行列数的乘积等于原来数组的元素个数,如这里原来是324=24个元素,所以就不能分成(5,-1),因为24个元素不能被份成5行,若分成5行,则不论多少列,肯定有元素多出来或者不够用,也就是不能正好分成5行多少列。
■ 06 多维数组的访问
作一个3×4的数组
import numpy as np
a = np.arange(1,13,1).reshape(3,4)
a
输出如下:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
访问第一行的数字2,后面两个中括号,第一个中括号表示行号,第二个中括号表示列号:
a[0][1]
2
访问第二行数据[ 5, 6, 7, 8]:
a[1]
array([5, 6, 7, 8])
也可以用a[1][:]。
要同时访问多行多列可以如下操作:
a[1:3][0:2]
array([[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
来源:蝈蝈大数据工作坊http://www.ggbigdata.cn