快速入门机器学习必学基础库numpy【原创】

前言

哈喽,大家好,我是鑫哥。

想入门机器学习、深度学习或者数据分析的小白,编程基础就是Python编程,而最常用的一些库,像numpy,pandas,matplotlib,sklearn等这些库都必须熟记于心。如果学习深度学习的话,还必须有着深度学习理论基础,掌握一些主流的TensorFlow,pytorch等框架才能在这条路上走下去。

在如今这个技术更新飞速的时代,原来那种先学完理论,再去实战的学习方式,已经落后了。而一种更为推荐的做法是:边用边学,只要先掌握一些基本的理论,然后写代码实践,遇到问题再返回来补充理论的这样的一种学习方式。

所以我在这里总结了一个numpy的快速入门,让你能快速的上手项目,当你把 numpy常用的功能都熟练运用了,后面再通过阅读官方文档和源代码来深入学习。

Numpy是什么?

Python中的数组计算方式要追溯到1995年,当时Jim Hugunin创造Numeric库。之后10年里,许多科研编程社区开始利用Python进行数组编程,但类库的生态在2000年之后都是碎片化的。2005年,Travis Oliphant在Numeric和Numarray项目之上打造了NumPy,将社区整合到同一个数组计算框架下。

NumPy,是Numerical Python的简称,它是目前Python数值计算中最为重要的基础包。大多数计算包都提供了基于NumPy的科学函数功能,将NumPy的数组对象作为数据交换的通用语。

NumPy本身并不提供建模和科学函数,理解NumPy的数组以及基于数组的计算将帮助你更高效地使用基于数组的工具,比如pandas。

NumPy在内部将数据存储在连续的内存块上,这与其他的Python内建数据结构是不同的。NumPy的算法库是用C语言写的,可以针对全量数组进行复杂计算而不需要写Python循环。

NumPy的方法比Python方法要快10到100倍,并且使用的内存也更少。

Numpy编程工具

编程工具只推荐使用Jupyter Notebook,至于为什么,可以百度下。

Numpy安装

介绍两种安装方式:

1、如果想一次性获取python和科学计算包(包含numpy),推荐安装Anaconda,支持 Linux, Windows 和 Mac 系统。

2、如果已经安装过python,只想安装numpy, 最简单的方式是pip install numpy。如果网速太慢,推荐使用镜像安装pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

Numpy常用核心操作

NumPy的核心特征之一就是N-维数组对象——ndarray。ndarray是Python中一个快速、灵活的大型数据集容器。数组允许你使用类似于向量的操作语法在整块数据上进行数学计算。一个ndarray是一个通用的多维同类数据容器,也就是说,它包含的每一个元素均为相同类型。

下面就是numpy常用的核心操作:

导入numpy包

import numpy as np

生成ndarray

生成数组最简单的方式就是使用array函数。array函数接收任意的序列型对象(当然也包括其他的数组),生成一个新的包含传递数据的NumPy数组。

例如:

一维数组:

arr1 = np.array([1, 2, 3, 4, 5, 6.5])

支持嵌套多层,如二维数组:

arr2 = np.array([[1, 2, 3], [4, 5, 6]]

ndarray常用属性

用来表示数组每一维度的数量:arr2.shape

用来表示数组维度数量:arr2.ndim

用来表示数组的数据类型:arr2.dtype

用来表示数组内元素的个数:arr2.size

其他生成ndarray的快捷方式

一次性创建全0数组,例如:np.zeros(10)

一次性创建全1数组,例如:np.ones(10)

创建高维全0数组,例如:np.zeros((3,4))

生成随机数组,例如:np.random.randn(10)

类似Python内建函数range创建数组,例如:np.arange(10)

创建一个等差数列,例如:np.linspace(1,9,5)

注意:由于NumPy专注于数值计算,如果没有特别指明的话,这些快捷方式默认的数据类型是float64(浮点型)。

ndarray数据类型设置

创建数组的时候设置数据类型,例如:np.array([1,2,3], dtype=np.float64)

转换数据类型,例如:arr1.astype(np.int64), 但注意astype会新生成一个数组,

也可以使用其他数组类型进行转换,例如:arr1.astype(arr2.dtype)

ndarray算数计算

ndarray之所以重要是因为它允许你进行批量操作而无须任何for循环。NumPy用户称这种特性为向量化。

两个等尺寸数组之间的算术操作:

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

arr * arr 的结果就是 array([1,4,9])

一个数组和一个整数的算术操作:

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

arr * 5 的结果是 array([5,10,15])

两个数组比较会产生布尔数组:

arr1 = np.array([2,1,4])

arr > arr1 的结果是 array([False, True, False])

ndarray通用函数

通用函数,也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。某些简单函数接收一个或多个标量数值,并产生一个或多个标量结果,而通用函数就是对这些简单函数的向量化封装。

例如:

计算每个元素的平方根:np.sqrt(arr)

计算每个元素的平方:np.square(arr)

逐个元素地将x和y中元素的最大值计算出来:

x = np.random.randn(10)

y = np.random.randn(10)

np.maximun(x, y)

Numpy项目案例

通过上面常用核心功能的学习,我们有必要再通过一个项目实战下。通过Numpy+PIL库实现图片的手绘效果,是一个入门而且有趣的项目,我们实现了两种效果:普通版和高级版。

我们通过jupyter notebook来实现图片的处理,首先准备一张图片,我选了一张樱木花道的头像,如图:

首先执行命令:jupyter notebook 启动notebook

普通版

执行如下代码:

from PIL import Image
import numpy as np

# 通过Image.open打开本地图片生成JpegImageFile对象,并作为参数传入numpy.array方法生成图像的三维数组。
img = np.array(Image.open("yingmuhuadao.jpeg"))

# 查看三维数组的数量和类型
print(img.shape, img.ndim, img.dtype)

# 使用convert("L")生成灰度图像,表示:每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。
# 转换公式:L = R * 299/1000 + G * 587/1000+ B * 114/1000。
# 需要注意的是,如果进行了灰度图像的转换,生成的np图像数组会变成二维数组。
img = np.array(Image.open("yingmuhuadao.jpeg").convert("L"))
print(img.shape, img.ndim, img.dtype)

# 取像素互补值
b_img = 255 - img

# 压缩一定范围像素值(需要不停的调试值,达到一个满意的效果,下面这个压缩值达到最终的手绘效果还是挺满意的。)
b_img = (190/255)*b_img + 110

# fromarray 必须是uint8类型数组,其他类型会报错
f_img = Image.fromarray(b_img.astype("uint8"))
f_img

显示的手绘效果图:

进阶版

执行如下代码:

"""
高级版手绘的三个基本特点:
图片可单通道灰度图
边缘线条较重可当成黑色,相同或相近像素值趋向白色
光源效果下,灰度变化类似于人类视觉的远近
实现思路:
手绘风格高级版是在对图像进行灰度化的基础上,由立体效果和明暗效果叠加而成的。
灰度代表着图像的明暗变化,梯度值表示的是灰度的变化率,所以我们可以通过调整像素的梯度值来间接改进图像的明暗程度
立体效果通过添加虚拟深度值来实现
解决方案:
利用像素之间的梯度值和虚拟深度值对图像进行重构,根据灰度变化来模拟人类视觉的明暗程度
"""

from PIL import Image
import numpy as np

"""
0.读取图片,转化为数组
"""

# 获取灰度图像的像素矩阵
arr_img = np.array(Image.open("yingmuhuadao.jpeg").convert("L")).astype("float")

"""
1.计算 x,y,z 轴梯度值,归一化
照片对边缘区域更侧重,计算梯度是定位图片边缘部分最有效方式,
用灰度变化来模拟图片远近效果,depth 表示预设深度,z 轴默认梯度为 1。
"""
depth = 10.  # 取值范围(0-100) 立体化, 深度值
grad = np.gradient(arr_img)  # 取图像灰度的梯度值
grad_x, grad_y = grad  # 分别取横纵图像梯度值
grad_x = grad_x * depth / 100. # 对梯度值进行归一化操作
grad_y = grad_y * depth / 100.
A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.) # 再次对梯度值进行归一化操作
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A

"""
2.加入光源效果 
根据光源不同的入射角度,对x,y,z 各轴上的梯度值有不同程度的影响,
添加一个模拟光源,放置在斜上方,与 x , y 分别形成两个夹角,最后用正弦余弦函数计算出新的像素值。
"""
vec_el = np.pi / 2.2  # 光源的俯视角度,弧度值
vec_az = np.pi / 4.  # 光源的方位角度,弧度值
dx = np.cos(vec_el) * np.cos(vec_az) # 光源对 x轴的影响因子
dy = np.cos(vec_el) * np.sin(vec_az) # 光源对 y轴的影响因子
dz = np.sin(vec_el)  # 光源对z 轴的影响因子
b_img = 255 * (dx * uni_x + dy * uni_y + dz * uni_z) # 将各个方向上的梯度值乘上虚拟光源对各方向的影响因子,还梯度还原成灰度
b_img = b_img.clip(0, 255) # 对像素值低于0,高于255部分做截断处理 防止灰度值溢出
f_img = Image.fromarray(b_img.astype("uint8"))
f_img

显示的手绘效果图:

Numpy推荐学习网站

菜鸟学习网:

https://www.runoob.com/numpy/numpy-tutorial.html

官方中文网:

http://www.numpy.org.cn/

Numpy快速入门:

http://c.biancheng.net/numpy/

我是知道, 感谢各位人才的:点赞、收藏和评论,我们下期更精彩!

最后

更多Python知识尽在【Python都知道】公众号,欢迎大家!!
扫描下方二维码,关注公众号,了解更多Python内容


小白学堂 » 快速入门机器学习必学基础库numpy【原创】

就聊挣钱,一个带着你做副业的社群。

立即查看 了解详情