Python数据分析与挖掘技术概述

所谓数据分析,即对已知的数据进行分析,然后提取出一些有价值的信息,比如统计平均数,标准差等信息,数据分析的数据量可能不会太大,而数据挖掘,是指对大量的数据进行分析与挖倔,得到一些未知的,有价值的信息等,比如从网站的用户和用户行为中挖掘出用户的潜在需求信息,从而对网站进行改善等。
数据分析与数据挖掘密不可分,数据挖掘是对数据分析的提升。数据挖掘技术可以帮助我们更好的发现事物之间的规律。所以我们可以利用数据挖掘技术可以帮助我们更好的发现事物之间的规律。比如发掘用户潜在需求,实现信息的个性化推送,发现疾病与病状甚至病与药物之间的规律等。

数据分析的模块:

  1. Jupyter:web版的ipython,编程、写文档、记笔记、展示,画图方面的优势和数据展示方面的优势。
  2. numpy 高效处理数据,提供数组支持,很多模块都依赖它,比如pandas,scipy,matplotlib都依赖他,所以这个模块都是基础。所以必须先安装numpy。
  3. pandas 主要用于进行数据的采集与分析
  4. scipy 主要进行数值计算。同时支持矩阵运算,并提供了很多高等数据处理功能,比如积分,微分方程求样等。
  5. matplotlib 作图模块,结合其他数据分析模块,解决可视化问题
  6. statsmodels 这个模块主要用于统计分析
  7. Gensim 这个模块主要用于文本挖掘
  8. sklearn,keras 前者机器学习,后者深度学习。

Jupyter

一.启动

jupyter notebook
image.png

二、新建

image.png

三.选择编辑的模式

image.png
点击如上图所示的下拉框按钮,选择编辑模式,如“code(代码)”。

四.运行

image.png

五、快捷键设置

快捷键的设置方式是:Help>KeyBord Shortcuts
image.png
快速上手的方法:
快捷键 运行代码 shift + enter
image.png

Numpy

NumPy 是 Numerical Python 的缩写,它是一个由多维数组对象(ndarray)和处理这些数组的函数(function)集合组成的库。使用 NumPy 库,可以对数组执行数学运算和相关逻辑运算。NumPy 不仅作为 Python 的扩展包,它同样也是 Python 科学计算的基础包。

NumPy ndarray对象

NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块,您可以使用索引或切片的方式获取数组中的每个元素。
ndarray 对象有一个 dtype 属性,该属性用来描述元素的数据类型。

创建ndarray对象

  1. numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)
  2. object 表示一个数组序列。
  3. dtype 可选参数,通过它可以更改数组的数据类型。
  4. copy 可选参数,表示数组能否被复制,默认是 True
  5. order 以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列)/F(列序列)/A(默认)。
  6. ndim 用于指定数组的维度。

创建一维数组:

  1. import numpy
  2. a=numpy.array([1,2,3])#使用列表构建一维数组
  3. print(a)
  4. #类型
  5. print(type(a))

创建多维数组:

  1. b=numpy.array([[1,2,3],[4,5,6]])
  2. print(b)

如果要改变数组元素的数据类型,可以使用通过设置 dtype

  1. c=numpy.array([2,4,6,8],dtype="数据类型名称")
  2. dtype complex:复数

ndim查看数组维数

  1. import numpy
  2. arr = numpy.array([[1, 2, 3, 4], [4, 5, 6, 7], [9, 10, 11, 23]])
  3. print(arr.ndim)

reshape数组变维

数组的形状指的是多维数组的行数和列数。Numpy 模块提供 reshape() 函数可以改变多维数组行数和列数,从而达到数组变维的目的。因此数组变维即对数组形状的重塑。原始数据没有改变。

  1. e = numpy.array([[1,2],[3,4],[5,6]])
  2. print("原数组",e)
  3. e=e.reshape(2,3)
  4. print("新数组",e)

resize数组变维

原始的ndarray进行了修改

  1. e = numpy.array([[1,2],[3,4],[5,6]])
  2. print("原数组",e)
  3. e=e.resize(2,3)
  4. print("新数组",e)

数组置换

  1. e = numpy.array([[1,2],[3,4],[5,6]])
  2. e.T # 转置 行变成列,列变成行

NumPy数据类型

序号 数据类型 语言描述
1 bool_ 布尔型数据类型(True 或者 False)
2 int_ 默认整数类型,类似于 C 语言中的 long,取值为 int32 或 int64
3 intc 和 C 语言的 int 类型一样,一般是 int32 或 int 64
4 intp 用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64)
5 int8 代表与1字节相同的8位整数。值的范围是-128到127。
6 int16 代表 2 字节(16位)的整数。范围是-32768至32767。
7 int32 代表 4 字节(32位)整数。范围是-2147483648至2147483647。
8 int64 表示 8 字节(64位)整数。范围是-9223372036854775808至9223372036854775807。
9 uint8 代表1字节(8位)无符号整数。
10 uint16 2 字节(16位)无符号整数。
11 uint32 4 字节(32位)的无符号整数。
12 uint64 8 字节(64位)的无符号整数。
13 float_ float64 类型的简写。
14 float16 半精度浮点数,包括:1 个符号位,5 个指数位,10个尾数位。
15 float32 单精度浮点数,包括:1 个符号位,8 个指数位,23个尾数位。
16 float64 双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位。
17 complex_ 复数类型,与 complex128 类型相同。
18 complex64 表示实部和虚部共享 32 位的复数。
19 complex128 表示实部和虚部共享 64 位的复数。
20 str_ 表示字符串类型
21 string_ 表示字节串类型

数据类型对象

·数据类型对象(Data Type Object)又称 dtype 对象,主要用来描述数组元素的数据类型、大小以及字节顺序。同时,它也可以用来创建结构化数据。比如常见的 int64、float32 都是 dtype 对象的实例,其语法格式如下:

  1. import numpy as np
  2. a= np.dtype(np.int64)
  3. print(a)

数据类型标识码

字符 对应类型
b 代表布尔型
i 带符号整型
u 无符号整型
f 浮点型
c 复数浮点型
m 时间间隔(timedelta)
M datatime(日期时间)
O Python对象
S,a 字节串(S)与字符串(a)
U Unicode
V 原始数据(void)
  1. #定义字段名score,以及数组数据类型i1
  2. dt = np.dtype([('score','i1')])
  3. a = np.array([(55,),(75,),(85,)], dtype = dt)
  4. print(a)
  5. print(a.dtype)
  6. print(a['score'])

输出结果:

  1. 获取a数组:
  2. [(55,) (75,) (85,)]
  3. 数据类型对象dtype
  4. dtype([('score', 'i1')])
  5. 获取'score'字段分数
  6. [55 75 85]

定义结构化数据

通常情况下,结构化数据使用字段的形式来描述某个对象的特征。以下示例描述一位老师的姓名、年龄、工资的特征,该结构化数据其包含以下字段:

  • str 字段:name
  • int 字段:age
  • float 字段:salary
    1. import numpy as np
    2. teacher = np.dtype([('name','S20'), ('age', 'i1'), ('salary', 'f4')])
    3. #输出结构化数据teacher
    4. print(teacher)
    5. #将其应用于ndarray对象
    6. b = np.array([('ycs', 32, 6357.50),('jxe', 28, 6856.80)], dtype = teacher)
    7. print(b)
    输出结果:
    1. [('name', 'S20'), ('age', 'i1'), ('salary', '<f4')]
    2. #输出的name为bytes字节串类型
    3. [(b'ycs', 32, 6357.5) (b'jxe', 28, 6856.8)]

    astype类型修改

    1. c=numpy.array([2,4,6,8],dtype="int64")
    2. print(c)
    3. c.astype("int32")
    4. c.tostring() # ndarray序列化到本地

    NumPy数组属性

    | 属性名字 | 属性解释 | | —- | —- | | ndarray.shape | 数组维度的元组,比如 2 行 3 列的二维数组可以表示为(2,3),该属性可以用来调整数组维度的大小 | | ndarray.ndim | 数组维数 | | ndarray.size | 数组中的元素数量 | | ndarray.itemsize | 一个数组元素的长度(字节) | | ndarray.dtype | 数组元素的类型 | | ndarray.flags | 返回 ndarray 数组的内存信息,比如 ndarray 数组的存储方式,以及是否是其他数组的副本等。 |
  1. import numpy as np
  2. a = np.array([[2,4,6],[3,5,7]])
  3. print(a.shape)
  4. #三行两列
  5. a.shape = (3,2)
  6. print(a)
  1. import numpy as np
  2. #随机生成一个一维数组
  3. c = np.arange(24)
  4. print(c)
  5. print(c.ndim)
  6. #对数组进行变维操作
  7. e = c.reshape(2,4,3)
  8. print(e)
  9. print(e.ndim)
  1. #数据类型为int8,代表1字节
  2. import numpy as np
  3. x = np.array([1,2,3,4,5], dtype = np.int8)
  4. print (x.itemsize)
  1. #数组中的元素数量
  2. import numpy as np
  3. x = np.array([1,2,3,4,5], dtype = np.int8)
  4. print (x.size)
  1. #返回 ndarray 数组的内存信息
  2. import numpy as np
  3. x = np.array([1,2,3,4,5], dtype = np.int8)
  4. print (x.flags)

Numpy创建数组

1.numpy.empty()

numpy.empty() 创建未初始化的数组,可以指定创建数组的形状(shape)和数据类型(dtype)

  1. numpy.empty(shape, dtype = float, order = 'C')

它接受以下参数:

  • shape:指定数组的形状;
  • dtype:数组元素的数据类型,默认值是值 float;
  • order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(行优先顺序)。
    1. import numpy as np
    2. #3行 2列
    3. arr = np.empty((3,2), dtype = int)
    4. print(arr)
    注意:numpy.empty() 返回的数组带有随机值,但这些数值并没有实际意义。切记 empty 并非创建空数组

    2.numpy.zeros()

    该函数用来创建元素均为 0 的数组,同时还可以指定被数组的形状,语法格式如下:
  1. numpy. zeros(shape,dtype=float,order="C")
参数名称 说明描述
shape 指定数组的形状大小。
dtype 可选项,数组的数据类型
order “C”代表以行顺序存储,“F”则表示以列顺序存储
  1. import numpy as np
  2. #默认数据类型为浮点数
  3. a=np.zeros(6)
  4. print(a)
  5. b=np.zeros(6,dtype="complex64" )
  6. print(b)

3.numpy.ones()

返回指定形状大小与数据类型的新数组,并且新数组中每项元素均用 1 填充,语法格式如下:

  1. numpy.ones(shape, dtype = None, order = 'C')
  1. import numpy as np
  2. arr1 = np.ones((3,2), dtype = int)
  3. print(arr1)

4.numpy.asarray()

asarray() 与 array() 类似,但是它比 array() 更为简单。asarray() 能够将一个 Python 序列转化为 ndarray 对象,语法格式如下:

  1. numpy.asarraysequencedtype = None order = None

它接受下列参数:

  • sequence:接受一个 Python 序列,可以是列表或者元组;
  • dtype:可选参数,数组的数据类型;
  • order:数组内存布局样式,可以设置为 C 或者 F,默认是 C。

    1. import numpy as np
    2. l=[1,2,3,4,5,6,7]
    3. a = np.asarray(l);
    4. print(type(a))
    5. print(a)

    5.numpy.frombuffer()

    表示使用指定的缓冲区创建数组。下面给出了该函数的语法格式:

    1. numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)

    它的参数说明如下所示:

  • buffer:将任意对象转换为流的形式读入缓冲区;

  • dtype:返回数组的数据类型,默认是 float32;
  • count:要读取的数据数量,默认为 -1 表示读取所有数据;
  • offset:读取数据的起始位置,默认为 0。
    1. import numpy as np
    2. #字节串类型
    3. l = b'hello world'
    4. print(type(l))
    5. a = np.frombuffer(l, dtype = "S1")
    6. print(a)
    7. print(type(a))

    6.numpy.fromiter()

    该方法可以把迭代对象转换为 ndarray 数组,其返回值是一个一维数组。
  1. numpy.fromiter(iterable, dtype, count = -1)

参数说明如下:

参数名称 描述说明
iterable 可迭代对象。
dtype 返回数组的数据类型。
count 读取的数据数量,默认为 -1,读取所有数据。
  1. import numpy as np
  2. # 使用 range 函数创建列表对象
  3. list=range(6)
  4. #生成可迭代对象i
  5. i=iter(list)
  6. #使用i迭代器,通过fromiter方法创建ndarray
  7. array=np.fromiter(i, dtype=float)
  8. print(array)

7.拷贝

  1. data1 = np.array(score) # 深拷贝
  2. data2 = np.asarray(score) # 浅拷贝
  3. data3 = np.copy(score) # 深拷贝

NumPy创建区间数组

1. numpy.arange()

在 NumPy 中,您可以使用 arange() 来创建给定数值范围的数组,语法格式如下:

  1. numpy.arange(start, stop, step, dtype)

参数说明见下表:

参数名称 参数说明
start 起始值,默认是 0。
stop 终止值,注意生成的数组元素值不包含终止值。
step 步长,默认为 1。
dtype 可选参数,指定 ndarray 数组的数据类型。

根据start与stop指定的范围以及step步长值,生成一个 ndarray 数组,示例如下。

  1. import numpy as np
  2. x = np.arange(8)
  3. print (x)

2. numpy.linspace()

表示在指定的数值区间内,返回均匀间隔的一维等差数组,默认均分 50 份,语法格式如下:

  1. np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

参数说明如下:

  • start:代表数值区间的起始值;
  • stop:代表数值区间的终止值;
  • num:表示数值区间内要生成多少个均匀的样本。默认值为 50;
  • endpoint:默认为 True,表示数列包含 stop 终止值,反之不包含;
  • retstep:默认为 True,表示生成的数组中会显示公差项,反之不显示;
  • dtype:代表数组元素值的数据类型。
    1. import numpy as np
    2. #生成10个样本
    3. a = np.linspace(1,10,10)
    4. print(a)

    3. numpy.logspace

    该函数同样返回一个 ndarray 数组,它用于创建等比数组,语法格式如下:
    1. np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
    其中 base 代表对数函数的底数,默认为 10,参数详细说明见下表:
参数名称 说明描述
start 序列的起始值:base**start。
stop 序列的终止值:base**stop。
num 数值范围区间内样本数量,默认为 50。
endpoint 默认为 True 包含终止值,反之不包含。
base 对数函数的 log 底数,默认为10。
dtype 可选参数,指定 ndarray 数组的数据类型。
  1. import numpy as np
  2. a = np.logspace(1,10,num = 10, base = 2)
  3. print(a)
  1. np.linspace(0, 10, 5) # 生成[0,10]之间等距离的5个数
  2. np.arange(0, 11, 5) # [0,11),5为步长生成数组

Numpy索引和切片

在 NumPy 中,如果想要访问,或修改数组中的元素,您可以采用索引或切片的方式,比如使用从 0 开始的索引依次访问数组中的元素,这与 Python 的 list 列表是相同的。
NumPy 提供了多种类型的索引方式,常用方式有两种:基本切片与高级索引。

基本切片

NumPy 内置函数 slice() 可以用来构造切片对象,该函数需要传递三个参数值分别是 start(起始索引)、stop(终止索引) 和 step(步长) ,通过它可以实现从原数组的上切割出一个新数组。

  1. import numpy as np
  2. a = np.arange(10)
  3. #生成切片对象
  4. s = slice(2,9,3)#从索引2开始到索引9停止,间隔时间为2
  5. print(a[s])

下面对冒号切片做简单地说明:

  • 如果仅输入一个参数,则将返回与索引相对应的元素。 对于上述示例来说[3] 就会返回 3。
  • 如果在其前面插入“:”如[:9],则会返回 0-8 的所有数字(不包含9)。
  • 如是 [2:] 则会返回 2-9 之间的数字。
  • 如果在两个参数之间,如[2:9],则对两个索引值之间的所有元素进行切片(不包括停止索引)。

多维数组切片
多维数组切片操作,实例如下:

  1. import numpy as np
  2. a = np.array([[1,2,3],[3,4,5],[4,5,6]])
  3. print(a)
  4. # 从[1:]索引处开始切割
  5. print(a[1:])

输出结果:

  1. [[1 2 3]
  2. [3 4 5]
  3. [4 5 6]]
  4. #切割后的新数组
  5. [[3 4 5]
  6. [4 5 6]]

注意:切片还可以使用省略号“…”,如果在行位置使用省略号,那么返回值将包含所有行元素,反之,则包含所有列元素。

  1. import numpy as np
  2. #创建a数组
  3. a = np.array([[1,2,3],[3,4,5],[4,5,6]])
  4. #返回数组的第二列
  5. print (a[...,1])
  6. #返回数组的第二行
  7. print (a[1,...])
  8. #返回第二列后的所有项
  9. print (a[...,1:])

高级索引

高级索引返回的是数组的副本(深拷贝),而切片操作返回的是数组视图(浅拷贝)

1. 整数数组索引

整数数组索引,它可以选择数组中的任意一个元素,比如,选择第几行第几列的某个元素,示例如下:

  1. import numpy as np
  2. #创建二维数组
  3. x = np.array([[1, 2], [3, 4], [5, 6]])
  4. #[0,1,2]代表行索引;[0,1,0]代表列索引
  5. y = x[[0,1,2],[0,1,0]]
  6. print (y)

2. 布尔数组索引

当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。下面示例返回数组中大于 6 的的所有元素:

  1. #返回所有大于6的数字组成的数组
  2. import numpy as np
  3. x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
  4. print (x[x > 6])

NumPy广播机制

NumPy 中的广播机制(Broadcast)旨在解决不同形状数组之间的算术运算问题。我们知道,如果进行运算的两个数组形状完全相同,它们直接可以做相应的运算。示例

  1. import numpy as np
  2. a = np.array([0.1,0.2,0.3,0.4])
  3. b = np.array([10,20,30,40])
  4. c = a * b
  5. print(c)

但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?当然不是!为了保持数组形状相同,NumPy 设计了一种广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。
当进行运算的两个数组形状不同,Numpy 会自动触发广播机制。示例如下:

  1. import numpy as np
  2. a = np.array([[ 0, 0, 0],
  3. [10,10,10],
  4. [20,20,20],
  5. [30,30,30]])
  6. #b数组与a数组形状不同
  7. b = np.array([1,2,3])
  8. print(a + b)

下图 1 :通过数组 a 、b 的运算展示了广播机制的实现流程。
image.png
4x3 的二维 a 数组 与 1x3 的一维 b 数组相加,本质上可以理解为 b 数组在纵向上向下拓展 3 次(将第一行重复 3 次),从而生成与 a 数组相同形状的数组,之后再与 a 数组进行运算。

NumPy遍历数组

NumPy 提供了一个 nditer 迭代器对象,它可以配合 for 循环完成对数组元素的遍历。

  1. import numpy as np
  2. #使用 arange() 函数创建一个 3*4 数组,并使用 nditer 生成迭代器对象
  3. a = np.arange(0,60,5)
  4. a = a.reshape(3,4)
  5. #使用nditer迭代器,并使用for进行遍历
  6. for x in np.nditer(a):
  7. print(x)

遍历顺序

在内存中,Numpy 数组提供了两种存储数据的方式,分别是 C-order(行优先顺序)与 Fortrant-order(列优先顺序)。那么 nditer 迭代器又是如何处理具有特定存储顺序的数组呢?其实它选择了一种与数组内存布局一致的顺序,之所以这样做,是为了提升数据的访问效率。
在默认情况下,当我们遍历数组中元素的时候,不需要考虑数组的存储顺序,这一点可以通过遍历上述数组的转置数组来验证。

  1. import numpy as np
  2. a = np.arange(0,60,5)
  3. a = a.reshape(3,4)
  4. #a的转置数组
  5. b = a.T
  6. print (b)
  7. for x in np.nditer(b):
  8. print(xend=",")

指定遍历顺序

可以通过 nditer 对象的order参数来指定数组的遍历的顺序。

import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print(a)
for x in np.nditer(a, order = 'C'):
   print (x,end=",") 
for x in np.nditer(a, order = 'F'):
   print (x,end=",")

修改数组元素值

nditer 对象提供了一个可选参数op_flags,它表示能否在遍历数组时对元素进行修改。它提供了三种模式,如下所示:

1) read-only

只读模式,在这种模式下,遍历时不能修改数组中的元素。

2) read-write

读写模式,遍历时可以修改元素值。

3) write-only

只写模式,在遍历时可以修改元素值。

import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4) 
print ("原数组是:",a)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...]=2*x
print ('修改后的数组是:',a)

NumPy相关数组操作

NumPy 中包含了一些处理数组的常用方法,大致可分为以下几类:

  • 数组变维操作
  • 数组转置操作
  • 修改数组维度操作
  • 连接与分割数组操作

    数组变维操作

    | 函数名称 | 函数介绍 | | —- | —- | | reshape | 在不改变数组元素的条件下,修改数组的形状。 | | flat | 返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。 | | flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。 | | ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。 |

1) numpy.ndarray.flat

numpy.ndarray.flat 返回一个数组迭代器,实例如下:

import numpy as np
a = np.arange(9).reshape(3,3)
for row in a:
    print (row)
#使用flat属性:
for ele in a.flat:
    print (ele,end=",")

2) numpy.ndarray.flatten()

numpy.ndarray.flatten 返回一份数组副本,对副本修改不会影响原始数组,其语法格式如下:

ndarray.flatten(order='C')
import numpy as np
a = np.arange(8).reshape(2,4)
print (a)
#默认按行C风格展开的数组
print (a.flatten())
#以F风格顺序展开的数组
print (a.flatten(order = 'F'))

3) numpy.ravel()

numpy.ravel() 将多维数组中的元素以一维数组的形式展开,该方法返回数组的视图(view),如果修改,则会影响原始数组。

numpy.ravel(a, order='C')
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print ('调用 ravel 函数后:')
print (a.ravel())
print ('F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))

数组转置操作

函数名称 说明
transpose 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。
ndarray.T 与 transpose 方法相同。
rollaxis 沿着指定的轴向后滚动至规定的位置。
swapaxes 对数组的轴进行对换。

1) numpy.transpose()

numpy.transpose() 用于对换多维数组的维度,比如二维数组使用此方法可以实现矩阵转置,语法格式如下:

numpy.transpose(arr, axes)

参数说明如下:

  • arr:要操作的数组
  • axes:可选参数,元组或者整数列表,将会按照该参数进行转置。

    import numpy as np
    a = np.arange(12).reshape(3,4)
    print (a)
    print (np.transpose(a))
    

    ndarray.T 的使用方法与其类似

    2) numpy.rollaxis()

    该方法表示沿着指定的轴,向后滚动至一个特定位置,格式如下:

    numpy.rollaxis(arr, axis, start)
    

    参数说明:

  • arr:要传入的数组;

  • axis:沿着哪条轴向后滚动,其它轴的相对位置不会改变;
  • start:默认以 0 轴开始,可以根据数组维度调整它的值。

    3) numpy.swapaxes()

    该方法用于交换数组的两个轴,其语法格式如下:
    numpy.swapaxes(arr, axis1, axis2)
    
    import numpy as np
    # 创建了三维的 ndarray
    a = np.arange(27).reshape(3,3,3)
    print (a)
    #对换0轴与2轴
    print(np.swapaxes(a,2,0))
    

    修改数组维度操作

    修改数组维度的操作,主要有以下方法:
函数名称 描述说明
broadcast 生成一个模拟广播的对象。
broadcast_to 将数组广播为新的形状。
expand_dims 扩展数组的形状。
squeeze 从数组的形状中删除一维项。

1) numpy.broadcast()

返回值是数组被广播后的对象,该函数以两个数组作为输入参数,实例如下:

import numpy as np
a = np.array([[1], [2], [3]])
b = np.array([4, 5, 6]) 
# 对b广播a
d = np.broadcast(a,b) 
#d它拥有 iterator 属性
r,c = d.iters
print (next(r), next(c))
print (next(r), next(c))
# 使用broadcast将a与b相加
e = np.broadcast(a,b)
f=np.empty(e.shape)
f.flat=[x+y for (x,y) in e]
print(f)
print(a+b)

2) numpy.broadcast_to()

该函数将数组广播到新形状中,它在原始数组的基础上返回一个只读视图。 如果新形状不符合 NumPy 的广播规则,则会抛出 ValueError 异常。函数的语法格式如下:

numpy.broadcast_to(array, shape, subok)
import numpy as np
a = np.arange(4).reshape(1,4)
print("原数组",a)
print ('调用 broadcast_to 函数之后:')
print (np.broadcast_to(a,(4,4)))

3) numpy.expand_dims()

在指定位置插入新的轴,从而扩展数组的维度,语法格式如下:

numpy.expand_dims(arr, axis)

参数说明:

  • arr:输入数组
  • axis:新轴插入的位置

    import numpy as np
    x = np.array(([1,2],[3,4]))
    print ('数组 x:')
    print (x)
    # 在 0 轴处插入新的轴
    y = np.expand_dims(x, axis = 0)
    print ('数组 y:')
    print (y)
    print ('\n')
    print ('数组 x 和 y 的形状:')
    print (x.shape, y.shape)
    

    4) numpy.squeeze()

    删除数组中维度为 1 的项,例如,一个数组的 shape 是 (5,1),经此函数后,shape 变为 (5,) 。其函数语法格式如下:

    numpy.squeeze(arr, axis)
    

    参数说明:

  • arr:输入数的组;

  • axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。
    import numpy as np
    a = np.arange(9).reshape(1,3,3)
    print (a)
    b = np.squeeze(a)
    print (b)
    print ('数组 a 和 b 的形状:')
    print (x.shape, y.shape)
    

    连接与分割数组操作

    连接与分割数组是数组的两种操作方式,如下所示:
类型 函数名称 描述说明
连接数组方法 concatenate 沿指定轴连接两个或者多个相同形状的数组
stack 沿着新的轴连接一系列数组
hstack 按水平顺序堆叠序列中数组(列方向)
vstack 按垂直方向堆叠序列中数组(行方向)
分割数组方法 split 将一个数组分割为多个子数组
hsplit 将一个数组水平分割为多个子数组(按列)
vsplit 将一个数组垂直分割为多个子数组(按行)

1) 连接数组操作

numpy.concatenate() 沿指定轴连接相同形状的两个或多个数组,格式如下:

numpy.concatenate((a1, a2, ...), axis)

参数说明:

  • a1, a2, …:表示一系列相同类型的数组;
  • axis:沿着该参数指定的轴连接数组,默认为 0。

    import numpy as np
    #创建数组a
    a = np.array([[10,20],[30,40]])
    print (a)
    #创建数组b
    b = np.array([[50,60],[70,80]])
    print (b)
    #沿轴 0 连接两个数组
    print (np.concatenate((a,b)))
    #沿轴 1 连接两个数组
    print (np.concatenate((a,b),axis = 1))
    

    数组连接操作至少需要两个维度相同的数组,才允许对它们进行垂直或者水平方向上的操作。
    在垂直方向堆叠数组,示例如下:

    import numpy as np
    a = np.array([[1,2],[3,4]])
    b = np.array([[5,6],[7,8]])
    #垂直堆叠
    c = np.vstack((a,b))
    print (c)
    

    2) 分割数组操作

    numpy.split() 沿指定的轴将数组分割为多个子数组,语法格式如下:

    numpy.split(ary, indices_or_sections, axis)
    

    参数说明:

  • ary:被分割的数组

  • indices_or_sections:若是一个整数,代表用该整数平均切分,若是一个数组,则代表沿轴切分的位置(左开右闭);
  • axis:默认为0,表示横向切分;为1时表示纵向切分。 ```python import numpy as np a = np.arange(6)

    原数组

    print (a)

    将数组分为二个形状大小相等的子数组

    b = np.split(a,2) print (b)

    将数组在一维数组中标明要位置分割

    b = np.split(a,[3,4]) print (b)

arr1数组

arr1 = np.floor(10 * np.random.random((2, 6))) print(arr1)

拆分后数组

print(np.hsplit(arr1, 3))

<a name="u1wQQ"></a>
## NumPy数组元素增删改查
| 函数名称 | 描述说明 |
| --- | --- |
| resize | 返回指定形状的新数组。 |
| append | 将元素值添加到数组的末尾。 |
| insert | 沿规定的轴将元素值插入到指定的元素前。 |
| delete | 删掉某个轴上的子数组,并返回删除后的新数组。 |
| argwhere | 返回数组内符合条件的元素的索引值。 |
| unique | 用于删除数组中重复的元素,并按元素值由大到小返回一个新数组。 |

<a name="kuGzT"></a>
### 1. numpy.resize()
numpy.resize() 返回指定形状的新数组。
```python
numpy.resize(arr, shape)
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a)
#a数组的形状
print(a.shape)
b = np.resize(a,(3,2))
#b数组
print (b)
#b数组的形状
print(b.shape)
#修改b数组使其形状大于原始数组
b = np.resize(a,(3,3))
print(b)

2. numpy.append()

在数组的末尾添加值,它返回一个一维数组。

numpy.append(arr, values, axis=None)

参数说明:

  • arr:输入的数组;
  • values:向 arr 数组中添加的值,需要和 arr 数组的形状保持一致;
  • axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反。

    import numpy as np
    a = np.array([[1,2,3],[4,5,6]])
    #向数组a添加元素
    print (np.append(a, [7,8,9]))
    #沿轴 0 添加元素
    print (np.append(a, [[7,8,9]],axis = 0))
    #沿轴 1 添加元素
    print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
    

    3. numpy.insert()

    表示沿指定的轴,在给定索引值的前一个位置插入相应的值,如果没有提供轴,则输入数组被展开为一维数组。

    numpy.insert(arr, obj, values, axis)
    

    参数说明:

  • arr:要输入的数组

  • obj:表示索引值,在该索引值之前插入 values 值;
  • values:要插入的值;
  • axis:指定的轴,如果未提供,则输入数组会被展开为一维数组。

    import numpy as np
    a = np.array([[1,2],[3,4],[5,6]])
    #不提供axis的情况,会将数组展开
    print (np.insert(a,3,[11,12]))
    #沿轴 0 垂直方向
    print (np.insert(a,1,[11],axis = 0))
    #沿轴 1 水平方向
    print (np.insert(a,1,11,axis = 1))
    

    4. numpy.delete()

    该方法表示从输入数组中删除指定的子数组,并返回一个新数组。它与 insert() 函数相似,若不提供 axis 参数,则输入数组被展开为一维数组。

    numpy.delete(arr, obj, axis)
    

    参数说明:

  • arr:要输入的数组;

  • obj:整数或者整数数组,表示要被删除数组元素或者子数组;
  • axis:沿着哪条轴删除子数组。

    import numpy as np
    a = np.arange(12).reshape(3,4)
    #a数组
    print(a)
    #不提供axis参数情况
    print(np.delete(a,5))
    #删除第二列
    print(np.delete(a,1,axis = 1))
    #删除经切片后的数组
    a = np.array([1,2,3,4,5,6,7,8,9,10])
    print (np.delete(a, np.s_[::2]))
    

    5. numpy.argwhere()

    该函数返回数组中非 0 元素的索引,若是多维数组则返回行、列索引组成的索引坐标。

    import numpy as np
    x = np.arange(6).reshape(2,3)
    print(x)
    #返回所有大于1的元素索引
    y=np.argwhere(x>1)
    print(y)
    

    6. numpy.unique()

    用于删除数组中重复的元素,其语法格式如下:

    numpy.unique(arr, return_index, return_inverse, return_counts)
    

    参数说明:

  • arr:输入数组,若是多维数组则以一维数组形式展开;

  • return_index:如果为 True,则返回新数组元素在原数组中的位置(索引);
  • return_inverse:如果为 True,则返回原数组元素在新数组中的位置(索引);
  • return_counts:如果为 True,则返回去重后的数组元素在原数组中出现的次数。
    import numpy as np
    a = np.array([5,2,6,2,7,5,6,8,2,9])
    print (a)
    #对a数组的去重
    uq = np.unique(a)
    print (uq)
    #数组去重后的索引数组
    u,indices = np.unique(a, return_index = True)
    #打印去重后数组的索引
    print(indices)
    #去重数组的下标:
    ui,indices = np.unique(a,return_inverse = True)
    print (ui)
    #打印下标
    print (indices)
    #返回去重元素的重复数量
    uc,indices = np.unique(a,return_counts = True)
    print (uc)
    元素出现次数:
    print (indices)
    

    Ndarray运算

    运算符

    | 序号 | 函数 | 位运算符 | 描述说明 | | —- | —- | —- | —- | | 1 | bitwise_and | & | 计算数组元素之间的按位与运算。 | | 2 | bitwise_or | | | 计算数组元素之间的按位或运算。 | | 3 | invert | ~ | 计算数组元素之间的按位取反运算。 | | 4 | left_shift | << | 将二进制数的位数向左移。 | | 5 | right_shift | >> | 将二进制数的位数向右移。 |
import numpy as np 
a = 10 
b = 12 
print("a的二进制数:",bin(a)) 
print("b的二进制数:",bin(b)) 
print("将a与b执行按位与操作:",np.bitwise_and(a,b))  


print ('a 和 b 的位或:')
print (np.bitwise_or(a, b))

#数据类型为无符号整型uint8
arr = np.array([20],dtype = np.uint8) 
print("二进制表示:",np.binary_repr(20,8)) 
print(np.invert(arr)) 
#进行取反操作
print("二进制表示: ", np.binary_repr(235,8))  

#移动三位后的输出值
print (np.left_shift(20,3))
#打印移动后20的二进制数
print (np.binary_repr(20, width = 8))
#函数返回值的二进制数
print (np.binary_repr(160, width = 8))

#将40右移两位后返回值:
print (np.right_shift(40,2))
#移动后40的二进制数:
print (np.binary_repr(40, width = 8))
#移动后返回值的二进制数:
print (np.binary_repr(10, width = 8))

三角函数

NumPy 中提供了用于弧度计算的的 sin()(正弦)、cos()(余弦)和 tan()(正切)三角函数,arcsin,arcos 和 arctan 反三角函数。
若要想验证反三角函数的结果,可以通过 numpy.degrees() 将弧度转换为角度来实现,

import numpy as np 
arr = np.array([0, 30, 60, 90, 120, 150, 180]) 
#计算arr数组中给定角度的三角函数值
#通过乘以np.pi/180将其转换为弧度
print(np.sin(arr * np.pi/180)) 
print(np.cos(arr * np.pi/180)) 
print(np.tan(arr * np.pi/180))  

arr = np.array([0, 30, 60, 90]) 
#正弦值数组
sinval = np.sin(arr*np.pi/180) 
print(sinval) 
#计算角度反正弦,返回值以弧度为单位
cosec = np.arcsin(sinval) 
print(cosec) 
#通过degrees函数转化为角度进行验证
print(np.degrees(cosec)) 
#余弦值数组
cosval = np.cos(arr*np.pi/180) 
print(cosval) 
#计算反余弦值,以弧度为单位
sec = np.arccos(cosval) 
print(sec) 
#通过degrees函数转化为角度进行验证
print(np.degrees(sec)) 
#下面是tan()正切函数 
tanval = np.tan(arr*np.pi/180) 
print(tanval) 
cot = np.arctan(tanval) 
print(cot) 
print(np.degrees(cot))

舍入函数

NumPy 提供了三个舍入函数,介绍如下:

1) numpy.around()

该函数返回一个十进制值数,并将数值四舍五入到指定的小数位上。该函数的语法如下:

numpy.around(a,decimals)

参数说明:

  • a:代表要输入的数组;
  • decimals:要舍入到的小数位数。它的默认值为0,如果为负数,则小数点将移到整数左侧。

    import numpy as np 
    arr = np.array([12.202, 90.23120, 123.020, 23.202]) 
    print(arr) 
    print("数组值四舍五入到小数点后两位",np.around(arr, 2)) 
    print("数组值四舍五入到小数点后-1位",np.around(arr, -1))
    

    2) numpy.floor()

    该函数表示对数组中的每个元素向下取整数,即返回不大于数组中每个元素值的最大整数。示例如下:

    import numpy as np
    a = np.array([-1.8,  1.1,  -0.4,  0.9,  18])
    #对数组a向下取整
    print (np.floor(a))
    

    3) numpy.ceil()

    该函数与 floor 函数相反,表示向上取整。示例如下:

    import numpy as np
    a = np.array([-1.8,  1.1,  -0.4,  0.9,  18])
    #对数组a向上取整
    print (np.ceil(a))
    

    算术运算

    NumPy 数组的“加减乘除”算术运算,分别对应 add()、subtract()、multiple() 以及 divide() 函数。
    注意:做算术运算时,输入数组必须具有相同的形状,或者符合数组的广播规则,才可以执行运算。

    import numpy as np
    a = np.arange(9, dtype = np.float_).reshape(3,3)
    #数组a
    print(a)
    #数组b
    b = np.array([10,10,10])
    print(b)
    #数组加法运算
    print(np.add(a,b))
    #数组减法运算
    print(np.subtract(a,b))
    #数组乘法运算
    print(np.multiply(a,b))
    #数组除法运算
    print(np.divide(a,b))
    

    numpy.reciprocal()

    该函数对数组中的每个元素取倒数,并以数组的形式将它们返回。
    当数组元素的数据类型为整型(int)时,对于绝对值小于 1 的元素,返回值为 0,而当数组中包含 0 元素时,返回值将出现 overflow(inf) 溢出提示,示例如下:

    import numpy as np
    #注意此处有0
    a = np.array([0.25, 1.33, 1, 0, 100])
    #数组a默认为浮点类型数据
    print(a)
    #对数组a使用求倒数操作
    print (np.reciprocal(a))
    #b数组的数据类型为整形int
    b = np.array([100], dtype = int)
    print(b)
    #对数组b使用求倒数操作
    print( np.reciprocal(b) )
    

    numpy.power()

    该函数将 a 数组中的元素作为底数,把 b 数组中与 a 相对应的元素作幂 ,最后以数组形式返回两者的计算结果。示例如下:

    import numpy as np
    a = np.array([10,100,1000]) 
    #a数组
    print ('我们的数组是;')
    #调用 power 函数
    print (np.power(a,2))
    b数组
    b = np.array([1,2,3]) 
    print (b)
    调用 power 函数
    print (np.power(a,b))
    

    numpy.mod()

    返回两个数组相对应位置上元素相除后的余数,它与 numpy.remainder() 的作用相同 。

    import numpy as np
    a = np.array([11,22,33])
    b = np.array([3,5,7])
    #a与b相应位置的元素做除法
    print( np.mod(a,b))
    #remainder方法一样
    print(np.remainder(a,b))
    

    复数数组处理函数

    NumPy 提供了诸多处理复数类型数组的函数,主要有以下几个:

  • numpy.real() 返回复数数组的实部;

  • numpy.imag() 返回复数数组的虚部;
  • numpy.conj() 通过更改虚部的符号,从而返回共轭复数;
  • numpy.angle() 返回复数参数的角度,该函数的提供了一个 deg 参数,如果 deg=True,则返回的值会以角度制来表示,否则以以弧度制来表示。


示例如下所示:

import numpy as np
a = np.array([-5.6j, 0.2j, 11. , 1+1j])
print(a)
#real() 
print(np.real(a))
#imag() 
print(np.imag(a))
#conj()
print( np.conj(a))
#angle() 
print( np.angle(a))
#angle() 带参数deg
print (np.angle(a, deg = True))

通用判断函数

# 判断stock_change[0:2, 0:5]是否全是>0
np.all(stock_change[0:2, 0:5] > 0)
# 判断前5只股票这段期间是否有>0
np.any(stock_change[:5, :] > 0)

三元运算符

# np.where(布尔值,True的位置的值,False的位置的值)
np.where(temp > 0, 1, 0)
# 大于0.5且小于1
np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
# 大于0.5或小于-0.5
np.where(np.logical_or(temp > 0.5, temp < -0.5), 11, 3)

统计函数

NumPy 提供了许多统计功能的函数,比如查找数组元素的最值、百分位数、方差以及标准差等。

numpy.amin() 和 numpy.amax()

这两个函数用于计算数组沿指定轴的最小值与最大值:

  • amin() 沿指定的轴,查找数组中元素的最小值,并以数组形式返回;
  • amax() 沿指定的轴,查找数组中元素的最大值,并以数组形式返回。


对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向。
image.png

import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]]) 
print ('数组a是:')
print(a)
#amin()函数
print (np.amin(a))
#调用 amin() 函数,axis=1
print(np.amin(a,1))
#调用amax()函数
print(np.amax(a))
#再次调用amax()函数
print(np.amax(a,axis=0))

numpy.ptp()

numpy.ptp() 用于计算数组元素中最值之差值,也就是(最大值 - 最小值)。

import numpy as np 
a = np.array([[2,10,20],[80,43,31],[22,43,10]]) 
print("原数组",a) 
print("沿着axis 1:",np.ptp(a,1)) 
print("沿着axis 0:",np.ptp(a,0))

numpy.percentile()

百分位数,是统计学中使用的一种度量单位。该函数表示沿指定轴,计算数组中任意百分比分位数,语法格式如下:

numpy.percentile(a, q, axis)

函数 numpy.percentile() 的参数说明:

  • a:输入数组;
  • q:要计算的百分位数,在 0~100 之间;
  • axis:沿着指定的轴计算百分位数。
    import numpy as np 
    a = np.array([[2,10,20],[80,43,31],[22,43,10]]) 
    print("数组a:",a) 
    print("沿着axis=0计算百分位数",np.percentile(a,10,0)) 
    print("沿着axis=1计算百分位数",np.percentile(a,10,1))
    

    numpy.median()

    numpy.median() 用于计算 a 数组元素的中位数(中值):
    import numpy as np
    a = np.array([[30,65,70],[80,95,10],[50,90,60]])
    #数组a:
    print(a)
    #median()
    print(np.median(a))
    #axis 0
    print(np.median(a, axis = 0))
    #axis 1:
    print(np.median(a, axis = 1))
    

    numpy.mean()

    该函数表示沿指定的轴,计算数组中元素的算术平均值(即元素之总和除以元素数量)。示例如下:
    import numpy as np
    a = np.array([[1,2,3],[3,4,5],[4,5,6]]) 
    print ('我们的数组是:')
    print (a)
    print ('调用 mean() 函数:')
    print (np.mean(a))
    print ('沿轴 0 调用 mean() 函数:')
    print (np.mean(a, axis =  0))
    print ('沿轴 1 调用 mean() 函数:')
    print (np.mean(a, axis =  1))
    

    numpy.average()

    加权平均值是将数组中各数值乘以相应的权数,然后再对权重值求总和,最后以权重的总和除以总的单位数(即因子个数)。
    numpy.average() 根据在数组中给出的权重,计算数组元素的加权平均值。该函数可以接受一个轴参数 axis,如果未指定,则数组被展开为一维数组。
    下面举一个简单的示例:现有数组 [1,2,3,4] 和相应的权重数组 [4,3,2,1],它的加权平均值计算如下:
    加权平均值=(1 * 4 + 2 * 3 + 3 * 2 + 4 * 1)/(4 + 3 + 2 + 1)
    
    import numpy as np
    a = np.array([1,2,3,4]) 
    print('a数组是:')
    print(a)
    #average()函数:
    print (np.average(a))
    # 若不指定权重相当于对数组求均值
    we = np.array([4,3,2,1]) 
    #调用 average() 函数:')
    print(np.average(a,weights = we))
    #returned 为Ture,则返回权重的和 
    prin(np.average([1,2,3,4],weights =  [4,3,2,1], returned =  True))
    

    方差np.var()

    方差,在统计学中也称样本方差,如何求得方差呢?首先我们要知道全体样本的的平均值,然后再求得每个样本值与均值之差的平方和,最后对差的平方和求均值,公式如下(其中 n 代表元素个数):
    image.png
    示例如下:
    import numpy as np
    print (np.var([1,2,3,4]))
    

    标准差np.std()

    标准差是方差的算术平方根,用来描述一组数据平均值的分散程度。若一组数据的标准差较大,说明大部分的数值和其平均值之间差异较大;若标准差较小,则代表这组数值比较接近平均值。它的公式如下:
    std = sqrt(mean((x - x.mean())**2
    
    NumPy 中使用 np.std() 计算标准差。示例如下:
    import numpy as np
    print (np.std([1,2,3,4]))
    

    NumPy字符串处理函数

    NumPy 提供了许多字符串处理函数,它们被定义在用于处理字符串数组的 numpy.char 这个类中,这些函数的操作对象是 string 或者 unicode 字符串数组。如下表所示:
函数名称 描述
add() 对两个数组相应位置的字符串做连接操作。
multiply() 返回多个字符串副本,比如将字符串“ hello”乘以3,则返回字符串“ hello hello hello”。
center() 用于居中字符串,并将指定的字符,填充在原字符串的左右两侧。
capitalize() 将字符串第一个字母转换为大写。
title() 标题样式,将每个字符串的第一个字母转换为大写形式。
lower() 将数组中所有的字符串的大写转换为小写。
upper() 将数组中所有的字符串的小写转换为大写。
split() 通过指定分隔符对字符串进行分割,并返回一个数组序列,默认分隔符为空格。
splitlines() 以换行符作为分隔符来分割字符串,并返回数组序列。
strip() 删除字符串开头和结尾处的空字符。
join() 返回一个新的字符串,该字符串是以指定分隔符来连接数组中的所有元素。
replace() 用新的字符串替换原数组中指定的字符串。
decode() 用指定的编码格式对数组中元素依次执行解码操作。
encode() 用指定的编码格式对数组中元素依次执行编码操作。
import numpy as np  
print(np.char.add(['welcome','url'], [' to C net','is c.biancheng.net'] ))  
print (np.char.multiply('c.biancheng.net',3))
#np.char.center(string, width, fillchar) 
# string: 代表字符串,width: 表示长度,fillchar: 要填充的字符
print(np.char.center("c.bianchneg.net", 20, '*'))  
print (np.char.capitalize('python'))
print(np.char.title("welcome to china")) 
print(np.char.lower("WELCOME TO MYHOME")) 
print(np.char.upper("Welcome To Python")) 
print(np.char.split("Welcome To Python"),sep = " ")  
print("Splitting the String line by line..") 
print(np.char.splitlines("Welcome\nTo\nPython"))  

str = "     welcome to Python     "
print("原字符串:",str)  
print(np.char.strip(str)) 
print (np.char.join(':','Love'))
#也可指定多个分隔符
print (np.char.join([':','-'],['Love','Python']))

str = "Welcome to China" 
print("原字符串:",str) 
#更改后字符串
print(np.char.replace(str, "Welcome to","Hello"))  

#cp500国际编码
encode_str = np.char.encode("Welcome to China", 'cp500') 
decode_str =np.char.decode(encode_str, 'cp500') 
print(encode_str) 
print(decode_str)

NumPy排序和搜索功能

NumPy 提供了多种排序函数, 这些排序函数可以实现不同的排序算法。
排序算法特征主要体现在以下四个方面:执行速度,最坏情况下的复杂度,所需的工作空间以及算法的稳定性。下表列举了三种排序算法:

种类 速度 最坏复杂度 工作空间 稳定性
quicksort(快速排序) 1 O(n^2) 0 不稳定
mergesort(归并排序) 2 O(n * log(n)) ~n/2 稳定
heapsort(堆排序) 3 O(n * log(n)) 0 不稳定

numpy.sort()

numpy.sort() 对输入数组执行排序,并返回一个数组副本。它具有以下参数:
numpy.sort(a, axis, kind, order)

参数说明:

  • a:要排序的数组;
  • axis:沿着指定轴进行排序,如果没有指定 axis,默认在最后一个轴上排序,若 axis=0 表示按列排序,axis=1 表示按行排序;
  • kind:默认为 quicksort(快速排序);
  • order:若数组设置了字段,则 order 表示要排序的字段。

    import numpy as np 
    a = np.array([[3,7],[9,1]]) 
    print('a数组是:')
    print(a)
    #调用sort()函数
    print(np.sort(a))
    #按列排序:
    print(np.sort(a, axis = 0))
    #设置在sort函数中排序字段
    dt = np.dtype([('name',  'S10'),('age',  int)])
    a = np.array([("raju",21),("anil",25),("ravi",  17),  ("amar",27)], dtype = dt) 
    #再次打印a数组
    print(a)
    #按name字段排序
    print(np.sort(a, order = 'name'))
    

    numpy.argsort()

    argsort() 沿着指定的轴,对输入数组的元素值进行排序,并返回排序后的元素索引数组。示例如下:

    import numpy as np 
    a = np.array([90, 29, 89, 12]) 
    print("原数组",a) 
    sort_ind = np.argsort(a) 
    print("打印排序元素索引值",sort_ind) 
    #使用索引数组对原数组排序
    sort_a = a[sort_ind] 
    print("打印排序数组") 
    for i in sort_ind: 
      print(a[i],end = " ")
    

    numpy.lexsort()

    numpy.lexsort() 按键序列对数组进行排序,它返回一个已排序的索引数组,类似于 numpy.argsort()。

    import numpy as np 
    a = np.array(['a','b','c','d','e']) 
    b = np.array([12, 90, 380, 12, 211]) 
    ind = np.lexsort((a,b)) 
    #打印排序元素的索引数组
    print(ind) 
    #使用索引数组对数组进行排序
    for i in ind: 
      print(a[i],b[i])
    

    NumPy 提供了许多可以在数组内执行搜索功能的函数。比如查找最值或者满足一定条件的元素。

    numpy.nonzero()

    该函数从数组中查找非零元素的索引位置。示例如下:

    import numpy as np 
    b = np.array([12, 90, 380, 12, 211]) 
    print("原数组b",b) 
    print("打印非0元素的索引位置") 
    print(b.nonzero())
    

    numpy.where()

    numpy.where() 的返回值是满足了给定条件的元素索引值。

    import numpy as np 
    b = np.array([12, 90, 380, 12, 211]) 
    print(np.where(b>12)) 
    c = np.array([[20, 24],[21, 23]]) 
    print(np.where(c>20))
    

    numpy.extract()

    该函数的返回值是满足了给定条件的元素值,示例如下:

    import numpy as np
    x = np.arange(9.).reshape(3, 3)
    打印数组x:'
    print(x) 
    #设置条件选择偶数元素
    condition = np.mod(x,2)== 0
    #输出布尔值数组
    print(condition)
    #按condition提取满足条件的元素值
    print np.extract(condition, x)
    

    numpy.argmax()

    该函数返回最大值的的索引,与其相反的函数是 argmin() 求最小值索引 ,示例如下:

    import numpy as np
    a = np.array([[30,40,70],[80,20,10],[50,90,60]]) 
    #a数组
    print (a)
    #argmax() 函数
    print (np.argmax(a))
    #将数组以一维展开
    print (a.flatten())
    #沿轴 0 的最大值索引:
    maxindex = np.argmax(a, axis =  0) 
    print (maxindex)
    #沿轴 1 的最大值索引
    maxindex = np.argmax(a, axis =  1) 
    print (maxindex)
    

    numpy.argmin()

    argmin() 求最小值索引。示例如下:

    import numpy as np
    b= np.array([[3,4,7],[8,2,1],[5,9,6]]) 
    print  ('数组b:')
    print (b) 
    #调用 argmin()函数
    minindex = np.argmin(b) 
    print (minindex)
    #展开数组中的最小值:
    print (b.flatten()[minindex])
    #沿轴 0 的最小值索引:
    minindex = np.argmin(b, axis =  0) 
    print (minindex)
    #沿轴 1 的最小值索引:
    minindex = np.argmin(b, axis =  1) 
    print (minindex)
    

    NumPy副本和视图

    对 NumPy 数组执行些函数操作时,其中一部分函数会返回数组的副本,而另一部分函数则返回数组的视图。
    其实从内存角度来说,副本就是对原数组进行深拷贝,新产生的副本与原数组具有不同的存储位置。而视图可理解为对数组的引用,它和原数组有着相同的内存位置。

    赋值操作

    赋值操作是数组引用的一种方法。比如,将 a 数组赋值给变量 b,被赋值后的变量 b 与 a 组具有相同的内存 id。因此,无论操作 a、b 中哪个数组,另一个数组也会受到影响。例如下:

    import numpy as np 
    a = np.array([[1,2,3,4],[9,0,2,3],[1,2,3,19]]) 
    print("原数组",a) 
    print("a数组的ID:",id(a)) 
    b = a
    print("数组b的id:",id(b)) 
    b.shape = 4,3; 
    print("b数组形状的更改也会反映到a数组上:") 
    print(a)
    

    ndarray.view()

    ndarray.view() 返回一个新生成的数组副本,因此对该数组的操作,不会影响到原数组。下面看一组示例:

    import numpy as np 
    a = np.array([[1,2,3,4],[9,0,2,3],[1,2,3,19]]) 
    print("原数组",a) 
    print("数组a的ID:",id(a)) 
    b = a.view() 
    print("数组b的ID:",id(b)) 
    #打印b数组
    print(b) 
    #改变b数组形状
    b.shape = 4,3
    print("原数组a",a) 
    print("新数组b",b)
    

    切片创建视图

    使用切片可以创建视图数组,若要修改视图的就会影响到原数组,示例如下:

    import numpy as np
    arr = np.arange(10)
    print ('数组arr:')
    print (arr)
    #创建切片修改原数组arr
    a=arr[3:]
    b=arr[3:]
    a[1]=123
    b[2]=234
    print(arr)
    

    ndarray.copy()

    该方法返回原数组的副本,对副本的修改不会影响到原数组。示例如下:

    import numpy as np 
    a = np.array([[1,2,3,4],[9,0,2,3],[1,2,3,19]]) 
    print("原数组",a) 
    print("a数组ID:",id(a)) 
    b = a.copy() 
    print("b数组ID:",id(b)) 
    print("打印经过copy方法的b数组:") 
    print(b) 
    b.shape=4,3
    print("原数组",a) 
    print("经过copy方法的b数组",b)
    

    NumPy Matrix矩阵库

    NumPy 提供了一个 矩阵库模块numpy.matlib,该模块中的函数返回的是一个 matrix 对象,而非 ndarray 对象。矩阵由 m 行 n 列(m*n)元素排列而成,矩阵中的元素可以是数字、符号或数学公式等。

    matlib.empty()

    matlib.empty() 返回一个空矩阵,所以它的创建速度非常快。

    numpy.matlib.empty(shape, dtype, order)
    

    该函数的参数说明如下:

  • shape:以元组的形式指定矩阵的形状。

  • dtype:表示矩阵的数据类型。
  • order:有两种选择,C(行序优先) 或者 F(列序优先)。

    import numpy.matlib
    import numpy as np
    #矩阵中会填充无意义的随机值
    print(np.matlib.empty((2,2)))
    

    numpy.matlib.zeros()

    numpy.matlib.zeros() 创建一个以 0 填充的矩阵,示例如下:

    import numpy.matlib
    import numpy as np
    print(np.matlib.zeros((2,2)))
    

    numpy.matlib.ones()

    numpy.matlib.ones() 创建一个以 1 填充的矩阵。

    import numpy.matlib
    import numpy as np
    print(np.matlib.ones((2,2)))
    

    numpy.matlib.eye()

    numpy.matlib.eye() 返回一个对角线元素为 1,而其他元素为 0 的矩阵 。

    numpy.matlib.eye(n,M,k, dtype)
    
  • n:返回矩阵的行数;

  • M:返回矩阵的列数,默认为 n;
  • k:对角线的索引;
  • dtype:矩阵中元素数据类型。
    import numpy.matlib
    import numpy as np
    print (np.matlib.eye(n =  3, M =  4, k =  0, dtype =  float))
    

    numpy.matlib.identity()

    该函数返回一个给定大小的单位矩阵,矩阵的对角线元素为 1,而其他元素均为 0。
    import numpy.matlib
    import numpy as np
    print np.matlib.identity(5, dtype = float)
    

    numpy.matlib.rand()

    numpy.matlib.rand() 创建一个以随机数填充,并给定维度的矩阵。示例如下:
    import numpy.matlib
    import numpy as np
    print (np.matlib.rand(3,3))
    

    NumPy线性代数

    NumPy 提供了 numpy.linalg 模块,该模块中包含了一些常用的线性代数计算方法,下面对常用函数做简单介绍:
函数名称 描述说明
dot 两个数组的点积。
vdot 两个向量的点积。
inner 两个数组的内积。
matmul 两个数组的矩阵积。
det 计算输入矩阵的行列式。
solve 求解线性矩阵方程。
inv 计算矩阵的逆矩阵,逆矩阵与原始矩阵相乘,会得到单位矩阵。
import numpy as np
A=[1,2,3]
B=[4,5,6]
print(np.dot(A,B))

#二维数组
a = np.array([[100,200],
             [23,12]]) 
b = np.array([[10,20],
            [12,21]]) 
dot = np.dot(a,b) 
print(dot) 
#计算两个向量的点积结果
a = np.array([[100,200],[23,12]]) 
b = np.array([[10,20],[12,21]]) 
vdot = np.vdot(a,b) 
print(vdot)  

#数组之间的内积。当计算的数组是一维数组时,它与 dot() 函数相同,若输入的是多维数组则两者存在不同
A=[[1 ,10],
    [100,1000]]
B=[[1,2],
    [3,4]]
#inner函数
print(np.inner(A,B))
#dot函数
print(np.dot(A,B))
#返回两个矩阵的乘积,假如两个矩阵的维度不一致,就会产生错误
a = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
b = np.array([[23,23,12],[2,1,2],[7,8,9]]) 
mul = np.matmul(a,b) 
print(mul)  

#对角线元素来计算矩阵的行列式
a = np.array([[1,2],[3,4]]) 
print(np.linalg.det(a))

numpy.linalg.solve()

该函数用于求解线性矩阵方程组,并以矩阵的形式表示线性方程的解,如下所示:

3X  +  2 Y + Z =  10  
X + Y + Z = 6
X + 2Y - Z = 2

方程系数矩阵:
3   2   1 
1   1   1 
1   2  -1
方程变量矩阵:
X 
Y 
Z  
方程结果矩阵:
10 
6
2

如果用  m 、x、n 分别代表上述三个矩阵,其表示结果如下:
m*x=n 或 x=n/m

import numpy as np
m = np.array([[3,2,1],[1,1,1],[1,2,-1]])
print ('数组 m:')
print (m)
print ('矩阵 n:')
n = np.array([[10],[6],[2]])
print (n)
print ('计算:m^(-1)n:')
x = np.linalg.solve(m,n)
print (x)

numpy.linalg.inv()

该函数用于计算矩阵的逆矩阵,逆矩阵与原矩阵相乘得到单位矩阵。示例如下:

import numpy as np 
a = np.array([[1,2],[3,4]]) 
print("原数组:",a) 
b = np.linalg.inv(a) 
print("求逆:",b)

NumPy矩阵乘法

矩阵乘法是将两个矩阵作为输入值,并将 A 矩阵的行与 B 矩阵的列对应位置相乘再相加,从而生成一个新矩阵,如下图所示:
image.png
注意:必须确保第一个矩阵中的行数等于第二个矩阵中的列数,否则不能进行矩阵乘法运算。
矩阵乘法运算被称为向量化操作,向量化的主要目的是减少使用的 for 循环次数或者根本不使用。这样做的目的是为了加速程序的计算。

逐元素矩阵乘法

multiple() 函数用于两个矩阵的逐元素乘法,示例如下:

import numpy as np 
array1=np.array([[1,2,3],[4,5,6],[7,8,9]],ndmin=3) 
array2=np.array([[9,8,7],[6,5,4],[3,2,1]],ndmin=3) 
result=np.multiply(array1,array2) 
result

矩阵乘积运算

matmul() 用于计算两个数组的矩阵乘积。示例如下:

import numpy as np 
array1=np.array([[1,2,3],[4,5,6],[7,8,9]],ndmin=3) 
array2=np.array([[9,8,7],[6,5,4],[3,2,1]],ndmin=3) 
result=np.matmul(array1,array2) 
print(result)

矩阵点积

dot() 函数用于计算两个矩阵的点积。如下所示:

import numpy as np 
array1=np.array([[1,2,3],[4,5,6],[7,8,9]],ndmin=3) 
array2=np.array([[9,8,7],[6,5,4],[3,2,1]],ndmin=3) 
result=np.dot(array1,array2) 
print(result)

NumPy IO操作

NumPy IO 操作是以文件的形式从磁盘中加载 ndarray 对象。在这个过程中,NumPy 可以两种文件类型处理 ndarray 对象,一类是二进制文件(以.npy结尾),另一类是普通文本文件。
上述两种文件格式,分别对应着不同的 IO 方法,如下所示:

文件类型 处理方法
二进制文件 load() 和 save()
普通文本文件 loadtxt() 和 savetxt()

我们知道,文件会被保存在不同的计算机上(比如 Linux、Windows、MacOSX 等)。为了不受的计算机架构影响,NumPy 开发团队给 ndarray 对象引入了一种.npy文件格式,通过它来件实现对 ndarray 对象的保存。

numpy.save()

numpy.save() 方法将输入数组存储在.npy文件中。

numpy.save(file, arr, allow_pickle=True, fix_imports=True)

参数说明:

  • file:保存后的文件名称,其文件类型为.npy;
  • arr:要保存的数组
  • allow_pickle:可选项,布尔值参数,允许使用 pickle 序列化保存数组对象。
  • fix_imports:可选项,为了便于在 Pyhton2 版本中读取 Python3 保存的数据。

    import numpy as np
    a = np.array([1,2,3,4,5])
    np.save('first',a)
    

    使用 load() 从 first.npy 文件中加载数据

    import numpy as np
    b = np.load('first.npy')
    print( b)
    

    savetxt()

    savetxt() 和 loadtxt() 分别表示以文本格式存储数据或加载数据。其中 savetxt() 的语法格式如下:

    np.savetxt('filename文件路径', self.task, fmt="%d", delimiter=" ")
    

    参数说明:

  • filename:表示保存文件的路径;

  • self.task: 要保存数组的变量名;
  • fmt=”%d”: 指定保存文件的格式,默认是十进制;
  • delimiter=” “表示分隔符,默认以空格的形式隔开。
    import numpy as np
    a = np.array([1,2,3,4,5])
    np.savetxt('second.txt',a)
    #使用loadtxt重载数据
    b = np.loadtxt('second.txt')
    print(b)