目录

  • 1 模块一  Python与机器学习概述
    • 1.1 Python与机器学习简介
    • 1.2 发展历程
    • 1.3 基本语法
    • 1.4 帮助
    • 1.5 应用
    • 1.6 示例源代码(食品识别小小专家系统)
    • 1.7 示例代码   蜡笔小新
    • 1.8 小结
    • 1.9 Python基础教程(教&学资料)
      • 1.9.1 安装Python
      • 1.9.2 第一个python程序
      • 1.9.3 Python基础
      • 1.9.4 函数
      • 1.9.5 高级特性
      • 1.9.6 函数式编程
      • 1.9.7 模块
      • 1.9.8 面向对象编程
      • 1.9.9 面向对象高级编程
      • 1.9.10 错误、调试和测试
      • 1.9.11 IO编程
      • 1.9.12 进程和线程
      • 1.9.13 正则表达式
      • 1.9.14 常用内建模块
      • 1.9.15 常用第三方模块
      • 1.9.16 图形界面
      • 1.9.17 网络编程
      • 1.9.18 电子邮件
      • 1.9.19 访问数据库
      • 1.9.20 Web开发
      • 1.9.21 异步IO
      • 1.9.22 使用MicroPython
      • 1.9.23 实战训练(day1~~day10)
        • 1.9.23.1 Day 1 - 搭建开发环境
        • 1.9.23.2 Day 2 - 编写Web App骨架
        • 1.9.23.3 Day 3 - 编写ORM
        • 1.9.23.4 Day 4 - 编写Model
        • 1.9.23.5 Day 5 - 编写Web框架
        • 1.9.23.6 Day 6 - 编写配置文件
        • 1.9.23.7 Day 7 - 编写MVC
        • 1.9.23.8 Day 8 - 构建前端
        • 1.9.23.9 Day 9 - 编写API
        • 1.9.23.10 Day 10 - 用户注册和登录
      • 1.9.24 Day 11 - 编写日志创建页
      • 1.9.25 Day 12 - 编写日志列表页
      • 1.9.26 Day 13 - 提升开发效率
      • 1.9.27 Day 14 - 完成Web App
      • 1.9.28 Day 15 - 部署Web App
      • 1.9.29 Day 16 - 编写移动App
    • 1.10 FAQ
    • 1.11 阶段总结
  • 2 PYthon程序示例
    • 2.1 程序示例(一)初识程序
    • 2.2 程序示例(二)查看今天是今年的第几天
    • 2.3 程序示例(三)if elif else语句
    • 2.4 程序示例(四)元组,列表, 堆栈,队列
    • 2.5 程序示例(五)学玩游戏《学色彩  神魔三龟玩变色》
    • 2.6 程序示例(六)函数
    • 2.7 程序示例(七)字符串
    • 2.8 程序示例(八)文件
    • 2.9 程序示例(九)排序
    • 2.10 程序示例-机器学习中英单词翻译小专家
    • 2.11 程序示例      画花朵  &  画佩奇
    • 2.12 程序示例   华夏时钟
    • 2.13 示例:  显示图片,响声
    • 2.14 播放声音视频文件mp3、wmv、wav、m4a等)
    • 2.15 Python WEB开发技术实战
  • 3 模块2 NumPy数值计算
    • 3.1 ndarray创建与索引
    • 3.2 ndarray的基础操作
    • 3.3 ufunc
    • 3.4 小结
    • 3.5 习题与实训
  • 4 模块3   pandas基础
    • 4.1 pandas常用类
    • 4.2 DataFrame基础操作
    • 4.3 其他数据类型操作
    • 4.4 小结
    • 4.5 习题与实训
    • 4.6 练习题
  • 5 模块4 pandas进阶
    • 5.1 数据读取与写出
    • 5.2 DataFrame进阶
    • 5.3 数据准备
    • 5.4 小结
    • 5.5 习题与实训
    • 5.6 练习习题及解答(参考)
  • 6 模块5 Matplotlib基础绘图
    • 6.1 Matplotlib绘图基础
    • 6.2 分析特征关系常用图形
    • 6.3 分析特征内部数据状态常用图形
    • 6.4 小结
    • 6.5 习题与实训
  • 7 模块6 机器学习库 scikit-learn
    • 7.1 数据准备
    • 7.2 降维
    • 7.3 分类
    • 7.4 回归
    • 7.5 聚类
    • 7.6 模型选择
    • 7.7 小结
    • 7.8 习题与实训
  • 8 模块7 餐饮企业综合分析
    • 8.1 (案例)餐饮企业分析需求
    • 8.2 数据准备
    • 8.3 使用K-means算法进行客户价值分析
    • 8.4 使用决策树算法实现餐饮客户流失预测
    • 8.5 小结
    • 8.6 习题与实训
  • 9 模块8  通信运营商客户流失分析与预测
    • 9.1 通信运营商客户流失分析需求
    • 9.2 数据准备
    • 9.3 特征工程
    • 9.4 使用多层感知器算法实现通信运营商 客户流失预测
    • 9.5 小结
    • 9.6 习题与实训
  • 10 学习参考资源
    • 10.1 机器学习的通俗讲解
    • 10.2 十大机器学习算法及其应用
    • 10.3 常用机器学习算法优缺点及其应用领域
    • 10.4 轻松学会 Python turtle 绘图
    • 10.5 Python 习题库
      • 10.5.1 习题1
    • 10.6 上机操作实训库
    • 10.7 面试准备题
    • 10.8 Python 程序扩展名 及发布程序时的选择
    • 10.9 计算机Python考试大纲
    • 10.10 Python  基础知识点梳理
    • 10.11 Python常用模块大全
    • 10.12 机器学习基本术语
    • 10.13 几个机器学习的成功案例
    • 10.14 60个机器学习算法应用场景实例
  • 11 章节测验(必测)
    • 11.1 测验一
    • 11.2 测验二
    • 11.3 测验三
    • 11.4 测验四
    • 11.5 测验五
    • 11.6 测验六
    • 11.7 测验七
    • 11.8 测验八
    • 11.9 测验九
    • 11.10 测验十
    • 11.11 编程专项测验
    • 11.12 填空题专项测验
    • 11.13 判断题专项测试
    • 11.14 简答题专项测试
    • 11.15 《机器学习技术》总复习
    • 11.16 书本--习题参考解答
  • 12 综合实训项目及展示
    • 12.1 项目(一)作品展示(1)
    • 12.2 项目(一)作品展示(2)
    • 12.3 团队项目实训(必作!)
ufunc

ufunc是universal function的缩写,意思是这些函数能够作用于narray对象的每一个元素上,而不是针对narray对象操作,numpy提供了大量的ufunc的函数。ufunc是一种对数组的每个元素进行运算的函数。NumPy的内置许多函数都是用C语言实现的因此,他们的计算速度十分的快。

这些函数在对narray进行运算的速度比使用循环或者列表推导式要快很多,但请注意,在对单个数值进行运算时,python提供的运算要比numpy效率高。

四则运算

numpy提供的四则ufunc有如下一些:
这里写图片描述
numpy提供的四则运算unfunc能够大大的提高计算效率,但如果运算式复杂,且参与运算的narray过大,会产生大量的中间结果,从而降低计算效率。例如:计算x=a*b+c时,实际上会按照如下方式计算:

t = a*b
x = t+c
del t

这会产生两次内存分配,一次时x,一次时t,所以按照

x = a*b
x = x+c

会节省一次内存的分配,从而提高效率。

#比较运算 & bool运算

numpy同时提供了=、<、>等这些比较运算符,这些运算符的结果是bool值或者bool数组。
这里写图片描述

np.array([1,2,3]) < np.array([0,3,4])
array([False,  True,  True], dtype=bool)12

逻辑运算and、or、not、xor等由于python提供了,所以numpy的这些逻辑运算符是以logical_开头的函数

a = np.arange(5)
b= np.arange(4,-1,-1)
## print a==b
[False False  True False False]
## print a>b
[False False False  True  True]
## print np.logical_or(a == b, a > b)
[False False  True  True  True]12345678

对两个bool数组进行逻辑运算时,将发生ValueError异常,因为bool值也是True和False,numpy无法确定运算目的,可以使用numpy.any()和numpy.all()函数,他们的使用方法和python的any()、all()函数用法相同。以bitwise_开头的函数时用于位运算,如(bitwise_and、bitwise_or)等,也可以使用&、|、~和^来进行运算。
除了numpy提供的内置ufunc函数,用户也可以编写自定义的ufunc函数,方式是:
1. 编写对单个数值计算的目的函数;
2. 利用np.frompyfunc(func, nin, nout)将其转换为ufunc函数,其中func是上面编写的目的函数,nin是输入的参数个数,nout是返回值的个数。

## 基本形式
u_func = np.frompyfunc(func,nin,nout)
ret = u_func(narray_obj,param1,param2..)123

这里返回的ret是object类型,所以实际上需要用astype()转换为目的类型。numpy.vectorize()也实现了和numpy.frompyfunc()一样的功能,区别是前者可以t通过otypes指定返回值的类型,不用再用astype()进行转换。

## 基本形式
u_func = np.frompyfunc(func,otypes=[dtype1,dtype2..]
ret = u_func(narray_object,param1,param2..)123

#广播

先看个例子:

a = np.arange(0,60,10).reshape(-1,1)
b = np.arange(0,5)
#a
array([[ 0],
       [10],
       [20],
       [30],
       [40],
       [50]])
#b
array([0, 1, 2, 3, 4])1234567891011

ok,现在计算a+b,不过现在有一个问题,a和b的维度不一样,那应该怎么加?先看看结果吧

# a+b
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [40, 41, 42, 43, 44],
       [50, 51, 52, 53, 54]])1234567

结果来看,是用a的每一行的元素(这里a为列向量,每一行只有一个元素)与b的每一个元素相加,相当于:

a=array([[ 0,  0,  0,  0,  0],
       [10, 10, 10, 10, 10],
       [20, 20, 20, 20, 20],
       [30, 30, 30, 30, 30],
       [40, 40, 40, 40, 40],
       [50, 50, 50, 50, 50]])123456

而b是一个行向量,现在我们将这一个行向量重复6次,和a的第0轴长度相同,构成一个二维数组,相当于:

b=array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])123456

现在,再进行相加,自然就是对用元素相加了,也就是上面的结果,这就是numpy中的广播,对进行运算的两个narray对象shape不一样时,进行的维度补齐。总的来说,numpy的广播规则基于下面4个规则:

  1. 让所有输入数姐都向其中维数最多的数组看齐,shape属性中不足的部分都通过在前面加1补齐; 如上面的输入中,a.shape=(6,1),b.shape=(,5),a的维数是2,b的维数是1,所以b向a看齐,并且用1补齐,那么b.shape=(1,5)。

  2. 输出数组的shape属性是输入数组的shape属性的各个轴上的最大值 输出是各轴上最大值,所以a+b的输出的shape应该是(6,5);

  3. 如果输入数组的某个轴的长度 为 1或与输出数组的对应轴的长度相同,这个数组能够用来计算,否则出错

  4. 当输入数组的某个轴的长度为1吋,沿着此轴运算时都用此轴上的第一组值

由于广播在numpy计算中比较常见,所以numpy提供了ogrid和mgrid来创建广播计算的数组,前者返回的是两个向量,后者返回的是进行广播运算的数组。

x,y = np.ogrid[:5,:5]
# x
array([[0],
       [1],
       [2],
       [3],
       [4]])
# y
array([[0, 1, 2, 3, 4]])
x,y=np.mgrid[:5,:5]
# x
[[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]]
#y
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]]12345678910111213141516171819202122

ogrid[]参数是有两种形式(1):[start:end:step]即起点、终点和步长;(2):[start:end:len]即起点、终点和数组长度,这里的长度为了和步长区分,在传入时时以虚数方式传入的,例如[1,5,4j]将产生[1,2,3,4]这样的数组。
另外广播支持特殊的下标None,意义时在对应位置上产生1的新轴,例如a[None,:]等效于a.reshape((1,-1)),a[:,None]等效于a.reshape((-1,1)),另外,np.ix_()能将一维数组转换为能进行广播的二维数组:

x=np.array([0,1,4,10])
y=np.array([2,3,8])
gy,gx=np.ix_(y,x)
#print gy
[[2]
[3]
[8]]
#print gx
[[ 0  1  4 10]]
# gx+gy
array([[ 2,  3,  6, 12],
       [ 3,  4,  7, 13],
       [ 8,  9, 12, 18]])12345678910111213

np.ix_()支持多个参数,从而支持n维空间的广播计算。

#ufunc方法

ufunc函数对象本身还有一些方法函数,这些方法只对两个输入、一个输出的ufunc 函数有效,其他的ufunc对象调用这些方法时会抛出ValueError异常。
(1). reduce(),沿着指定轴对数组进行操作,相当于将相应的操作放到该轴元素之间。

np.add.reduce([1,2,3])  #1+2+3=6
np.add.reduce([[1,2,3],[4,5,6]])  #[1+4,2+5,3+6]=[5,7,9]
np.add.reduce([[1,2,3],[4,5,6]],axis=1) #[1+2+3,4+5+6]=[6,15]123

(2). accumulate()和reduce()类似,区别时是前者会保留中间结果:

np.add.accumulate([1,2,3]) #[1,1+2,1+2+3]=[1,3,6]
np.add.accumulate([[1,2,3],[4,5,6]],axis=1) 
#
array([[ 1,  3,  6],
       [ 4,  9, 15]])12345

(3). reduceat()方法计算多纽reduce()的结果,通 过 indices参数指定一系列的起始和终止位置。它的计算有些特别,,计算的方法如下:

if indices[i] < indices[i+1]:
    result[i] = <op>.reduce(a[indices[i]:indices[i+1]])
else:
    result[i] = a[indices[i]]
#result[-1]的计算如下:
<op>.reduce(a[indices[-1]:])

例:
a = np.array([1,2,3,4])
result = np.add.reduceat(a, indices=[0,1,0,2,0,3,0])
## result
array([1,2,3,3,6,4,10])

## 计算过程如下:
1 : a[0] -> 1
2 : a[1] -> 2
3 : a[0] + a[1] -> 1 + 2
3 : a[2] -> 3
6 : a[0] + a[1] + a[2] -> 1 + 2 + 3 = 6
4 : a[3] -> 4
10 :a[0] + a[1] + a[2] + a[4] - > 1 + 2 + 3 + 4 = 1 0123456789101112131415161718192021

#再看多维数组

在前一篇文章中我们提到过多维数组,现在我们回头再看看多维数组的下标取数据。首先,多维数组的下标应该是一个长度和数组的维数相同的元组。如栗下标元组的长度比数组的维数大,就会出错;如果小,就 会 在 下 标 元 组 的 后 而 补 ,使得它的长度与数组维数相同。如果下标对象不是元组,则 numpy会首先把它转换为元组。这种转换可能会和用户所希望的不一致,因此为了避免出现问题,请 “显式”地使用元组作为下标。

a = np.arange(3*4*5).reshape(3,4,5)
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]],

       [[40, 41, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])

lidx=[[0],[1]]
#a[lidx]

aidx = np.array(lidx)
#a[aidx]
array([[[[ 0,  1,  2,  3,  4],
         [ 5,  6,  7,  8,  9],
         [10, 11, 12, 13, 14],
         [15, 16, 17, 18, 19]]],


       [[[20, 21, 22, 23, 24],
         [25, 26, 27, 28, 29],
         [30, 31, 32, 33, 34],
         [35, 36, 37, 38, 39]]]])12345678910111213141516171819202122232425262728293031

可以看到,numpy把列表[[0],[1]]转换成元组([0],[1]),而把数组对象转换成(aidx,:,:)。

整数数组和切片做为下标

如果利用数组作为下标,但数组的维度都不一样,那么这个时候这些数组将会应用广播规则把这些数组转换成一样,转换的规则是上面说到的先用1补足然后取各个维度的最大值。

i0 = np.array([[1,2,1],[0,1,0]])
i1 = np.array([[[0]],[[1]]])
i2 = np.array([[[2,3,2]]])
#print i0.shape
(2, 3)
#print i1.shape
(2, 1, 1)
#print i2.shape
(1, 1, 3)
# i0补齐之后为 (1,2,3),然后取最大值为
(2,2,3)1234567891011

这里将所有的数组进行广播,把所有的数组转换成shape=(2,2,3),利用numpy.broadcast_arrays()可以查看广播后的数组:

id0,id1,id2=np.broadcast_arrays(i0,i1,i2)
#id0
[[[1 2 1]
  [0 1 0]]

 [[1 2 1]
 [0 1 0]]
#id1
[[[0 0 0]
  [0 0 0]]

 [[1 1 1]
  [1 1 1]]]
#id2
[[[2 3 2]
  [2 3 2]]

 [[2 3 2]
  [2 3 2]]]12345678910111213141516171819

然后利用下标取元素时,例如i,j,k=1,1,1时,取得的元素应该是a[id0[i,j,k],id1[i,j,k],id2[i,j,k]]=a[1,1,3]=28。下标中含有切片时,首先来看第一种,就是整数数组时连续的,也就是数组之间没有切片,例如a[1:3,i0,i1],这种情况下,首先会把整数数组(i0,i1)广播,然后将切片的长度放到相应的位置构成一个维度,i0,i1广播后的shape=(2,2,3),切片的长度为2,所以最后的shape=(2,2,2,3)。最后的结果是a[1:3,id0[i,j,k],id1[i,j,k]]。再者,如果切片是再整数数组之间,那么同样会将数组广播,然后把切片位置替换为数组的维度或者切片的长度添加到索引的最后面,如a[i0,:,i1],i0,i1广播后的shape=(2,2,3),数组a的第二个轴的长度为4,所以最后的shape=(2,2,3,4)。

bool数组做为下标

用bool数组作为下标时,会将bool数组中为True的索引组成一个整数数组,然后以此数组作为下标。相当于用numpy.nonzero(bool_array)的结果,例如:

b2 = np.array([[True,False,True],[True,False,False]])
np.nonzero(b2)
##
(array([0, 0, 1]), array([0, 2, 0]))
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 
## 相当于取[0,0],[0,2],[1,0]
1234567

除此之外,如果bool数组中有切片,那么相当于将bool值转换成nonzero()后的整数数组,切片位置不变。