01.简介
- Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度数组
- Numpy支持常见的数组和矩阵操作,对于同样的数值计算任务,使用Numpy比直接使用Python要简洁得多
- Numpy使用ndarray对象处理多维数组,该对象是一个快速而灵活的大数据容器
02.ndarray介绍
- Numpy提供了一个N维数组类型ndarray
- 它描述了相同类型的items的集合
举例:将下面的表格转换为二维数组
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 创建ndarray
score = [
[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]
]
# 查看
print(score)
03.对比list和ndarray的效率
需求:分别使用list和ndarray求1-1000000之间所有数的和,并分别打印计算时间
# coding:utf-8
# 作者:理想国真恵玩
import functools
import time
import numpy as np
import random
def test_spend_time(func):
"""查看一段程序执行消耗的时间"""
@functools.wraps(func)
def inner(*args, **kwargs):
# 开始时间
start_time = time.time()
# 运行代码
result = func(*args, **kwargs)
# 结束时间
end_time = time.time()
# 计算运行时间
spend_time_result = end_time - start_time
# 打印
print(f'程序执行完毕,共耗时{spend_time_result}秒')
# 装饰完毕,返回被装饰函数的执行结果
return result
# 返回内部函数
return inner
# 列表
@test_spend_time
def sum_list():
result = sum(range(100000000))
return result
# ndarray
@test_spend_time
def sum_ndarray():
# 转换为ndarray对象
result = np.sum(np.arange(100000000))
return result
# 执行测试
print(sum_list())
print('----------------------')
print(sum_ndarray())
程序执行完毕,共耗时2.7865750789642334秒
4999999950000000
----------------------
程序执行完毕,共耗时0.22935819625854492秒
887459712
04.为什么使用ndarray
- 机器学习的最大特点就是大量的数据运算
- 而numpy处理大数据量计算有速度快的优势
- ndarray支持并行化运算(向量化运算)
- 效率远高于纯python代码,Numpy底层使用C语言编写
05.ndarray的属性
- ndarray.shape:数组维度的元组,表示几行几列
- ndarray.ndim:数组维数
- ndarray.size:数组中元素的数量
- ndarray.itemsize:一个数组元素的长度
- ndarray.dtype:数组元素的类型
示例代码
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.array([1, 2, 3])
print(arr, type(arr))
# ndarray.shape:数组维度的元组,表示几行几列
print(arr.shape)
# ndarray.ndim:数组维数
print(arr.ndim)
# ndarray.size:数组中元素的数量
print(arr.size)
# ndarray.itemsize:一个数组元素的长度
print(arr.itemsize)
# ndarray.dtype:数组元素的类型
print(arr.dtype)
06.生成0和1的数组
生成全是1的数组
- np.ones(shape,dtype)
- np.ones_like(array,dtype)
生成全是0的数组
- np.zeros(shape,dtype)
- np.zeros_like(array,dtype)
示例:创建全是0的数组
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 创建3行3列全是0的数组
zeros = np.zeros([3, 3])
print(zeros)
示例:创建全是1的数组
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 创建3行3列全是1的数组
ones = np.ones([3, 3])
print(ones)
07.列表转数组
- np.asarray(列表)
- np.array(列表)
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
list01 = [[1, 2, 3], [4, 5, 6]]
arr1 = np.asarray(list01)
# 修改
arr1[0, 0] = 111
print(list01)
print(arr1)
arr2 = np.array(list01)
arr2[0, 1] = 222
print('----------')
print(list01)
print(arr2)
08.生成等差数组
语法
np.linspace(start, stop, num, endpoint)
- 创建指定数量,指定范围的等差数组
- 参数
- start:开始值
- stop:结束值
- num:指定数量,默认50
- endpoint:是否包含结束值,默认为True
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 包含结束值
arr1 = np.linspace(1, 100, 10, True)
print(arr1)
# 不包含结束值
arr2 = np.linspace(1, 100, 10, False)
print(arr2)
[ 1. 12. 23. 34. 45. 56. 67. 78. 89. 100.]
[ 1. 10.9 20.8 30.7 40.6 50.5 60.4 70.3 80.2 90.1]
09.生成指定范围序列
语法
np.arange(start, stop, step, dtype)
- 创建指定步长的等差数组
- 参数
- start:开始值
- stop:结束值
- step:步长
- dtype:数据类型
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 生成1-100之间间隔为10的所有数
arr1 = np.arange(1, 100, 10, np.int)
print(arr1)
arr2 = np.arange(1, 100, 10, np.float)
print(arr2)
[ 1 11 21 31 41 51 61 71 81 91]
[ 1. 11. 21. 31. 41. 51. 61. 71. 81. 91.]
10.生成等比数列
语法
np.logspace(start, stop, num)
- 创建等比数列
- 参数
- start:开始值
- end:结束值
- num:要生成的等比数列数量,默认为50
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.logspace(2, 100, 5)
print(arr)
[1.00000000e+002 3.16227766e+026 1.00000000e+051 3.16227766e+075
1.00000000e+100]
11.正态分布
概念
-
正态分布是一种概率分布
-
正态分布是具有两个参数u和q的连续型随机变量的分布
- 第一个参数u是服从正态分布的随机变量的均值
- 第二个参数q是次随机变量的方差
- 所以正态分布记作:N(u, q)
-
u决定数据的分布范围(x轴)
-
q决定数据的胖瘦高低(y轴)
生活中的正态分布
- 身高的分布
- 收入的分布
12.创建正态分布数组
语法
np.random.normal(loc=0.0, scale=1.0, size=None)
- loc:此概率分布的均值,对应着整个分布的中心
- scale:此概率分布的标准差,越大越矮胖,越小越瘦高
- size:形状,默认只输出一个值
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.random.normal(1, 1, 5)
print(arr)
[ 1.17290559 2.3736328 -0.25809951 0.90265345 1.60211836]
13.绘制正态分布图
步骤分析
- 导入依赖
- 准备服从正态分布的数据
- 绘制图像
- 显示图像
示例
# coding:utf-8
# 作者:理想国真恵玩
# 导入依赖
import numpy as np
import matplotlib.pyplot as plt
# 准备服从正态分布的数据
x1 = np.random.normal(1.75, 1, 100000000) # 标准差为1,表示标准正态分布
# 绘制图像
plt.figure(figsize=(20, 12), dpi=100)
plt.hist(x1, 1000)
# 显示图像
plt.show()
14.模拟股票涨跌幅
案例:生成随机4支股票1周的交易日涨跌幅数据
np.random.normal(0, 1, (4,5)) # 4支股票,一周5天
步骤分析
- 导入依赖
- 准备数据
- 解决中文乱码
- 绘制图像
- 绘制标签
- 绘制刻度
- 绘制图例
- 绘制网格
- 保存图片
- 显示图片
示例
# coding:utf-8
# 作者:理想国真恵玩
# 导入依赖
import numpy as np
import matplotlib.pyplot as plt
# 准备数据
stock_change = np.random.normal(0, 1, (4, 5))
x = np.arange(5)
print(stock_change)
# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 绘制图像
plt.plot(x, stock_change[0], label='a')
plt.plot(x, stock_change[1], label='b')
plt.plot(x, stock_change[2], label='c')
plt.plot(x, stock_change[3], label='d')
# 绘制标签
plt.xlabel('时间')
plt.ylabel("交易额")
plt.title("四只股票一周涨跌额趋势图")
# 绘制图例
plt.legend()
# 绘制刻度
x_ticks = ['周一', '周二', '周三', '周四', '周五']
plt.xticks(x, x_ticks)
# 绘制网格
plt.grid()
# 保存图片
plt.savefig("./test.png")
# 显示图片
plt.show()
15.创建均匀分布数组
语法
np.random.uniform(low=0.0, high=1.0, size=None)
- 从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开
- 参数
- low:最小值
- high:最大值(不包含)
- size:数组形状,可以是所少个的数组,或者几行几列的数组
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 一维数组
arr1 = np.random.uniform(1, 100, 10)
# 二维数组
arr2 = np.random.uniform(1, 100, [2, 5])
print(arr1)
print(arr2)
[66.79060689 37.62377953 57.81861342 46.48315804 44.06721645 57.10224634
33.53473073 17.35717284 55.26746911 35.45114853]
[[90.48559329 71.84850177 62.24539414 77.13575803 44.84626324]
[39.46303874 73.40867777 81.0228404 7.5667691 52.04405069]]
16.数组的索引和切片
- 索引和列表索引一致
- 切片有所不同
一维数组
数组[行切片]
二维数组
数组[行切片,列切片]
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr1 = np.random.uniform(1, 100, 10)
print(arr1)
# 一维数组切片
print(arr1[1:5:2])
print('--------------')
arr2 = np.random.uniform(1, 100, (2, 5))
print(arr2)
# 二维数组切片
print(arr2[0:1, 1:4])
[16.02184403 24.25829158 96.74209496 68.58926571 60.44448884 37.9984101
38.00073312 76.24619593 25.27071314 46.44917045]
[24.25829158 68.58926571]
--------------
[[46.78828442 30.64910026 40.44394562 66.19264537 63.79926145]
[71.92414899 72.57794729 6.87442751 21.82083324 91.29206169]]
[[30.64910026 40.44394562 66.19264537]]
17.数组形状修改
ndarray.reshape(形状)
- 根据数组生成指定的形状的新数组
ndarray.resize(new_shape)
- 修改数组本身的形状
ndarray.T
- 转置,将数组的行列进行互换
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# reshape的使用
arr = np.arange(10).reshape((2, 5))
print(arr)
# resize的使用
arr.resize((5, 2))
print(arr)
# T的使用
arrT = arr.T
print(arrT)
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
[[0 2 4 6 8]
[1 3 5 7 9]]
18.类型修改
ndarray.astype(type)
- 返回修改了类型之后的数组
ndarray.tobytes()
- 转换为字节
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 转换类型
arr = np.arange(10).reshape([2, 5])
print(arr)
# 转换为float类型
arr1 = arr.astype(np.float)
print(arr1)
# 转换为字符串
arr2 = arr1.tobytes()
print(arr2)
[[0 1 2 3 4]
[5 6 7 8 9]]
[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]]
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00"@'
19.数组去重
np.unique(数组)
- 去掉数组中重复的元素
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr1 = np.array([1, 1, 1, 2, 2, 2, 3, 3, 4])
arr2 = np.array(arr1) # 深拷贝
print(arr1)
# 一维数组去重
arr1 = np.unique(arr1)
print(arr1)
# 二维数组去重
print('二维数组去重')
arr2.resize([3, 3])
print(arr2)
arr2 = np.unique(arr2)
print(arr2)
[1 1 1 2 2 2 3 3 4]
[1 2 3 4]
二维数组去重
[[1 1 1]
[2 2 2]
[3 3 4]]
[1 2 3 4]
20.数组逻辑运算
- 用法1:用于筛选
- 用法2:用于筛选并赋值
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 生成10名同学,5门功课的成绩
score = np.random.randint(40, 100, (10, 5))
print(score)
# 取出最后四名同学的成绩,用于逻辑判断
test_score = score[0:, 1:]
print(test_score)
# 逻辑判断,查询大于60分的成绩
print(test_score > 60)
# 赋值,将及格的成绩赋值为1
test_score[test_score > 60] = 1
print(test_score)
21.通用判断函数
np.all(数组 逻辑运算符 值)
- 数组的所有数据都满足逻辑表达式,则返回True
- 否则返回False
np.any(数组 逻辑运算符 值)
- 数组有任何一个数据满足逻辑表达式,则返回True
- 否则返回False
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.arange(10).reshape([2, 5])
print(arr)
# 判断第一行的数都小于5
print(np.all(arr[0:1, ] < 5))
print('--------')
# 判断第二行有任意一个数大于8
print(np.any(arr[1:, ] > 8))
22.逻辑运算符
np.where(条件,值1,值2)
- 满足条件则返回“值1”,否则返回“值2”
复合逻辑
- np.logical_and(条件1,条件2,条件3…)
- np.logical_or(条件1,条件2,条件3…)
用法举例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 生成2个学生的随机5门成绩
score = np.random.randint(40, 100, [2, 5])
print(score)
# 及格赋值为1,不及格赋值为0
test_score = np.where(score >= 60, 1, 0)
print(test_score)
# 大于80且小于90赋值为1,否则0
test_score1 = np.where(np.logical_and(score > 80, score < 90), 1, 0)
print(test_score1)
# 大于90或者小于60赋值为0,否则为1
test_score2 = np.where(np.logical_or(score > 90, score < 60), 0, 1)
print(test_score2)
[[51 52 51 96 74]
[62 95 85 81 71]]
[[0 0 0 1 1]
[1 1 1 1 1]]
[[0 0 0 0 0]
[0 0 1 1 0]]
[[0 0 0 0 1]
[1 0 1 1 1]]
23.统计运算
- min(数组,行1还是列0):求最小值
- max(数组,行1还是列0):求最大值
- median(数组,行1还是列0):求中位数
- mean(数组,行1还是列0):求均值
- std(数组,行1还是列0):求标准差
- var(数组,行1还是列0):求方差
示例
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.arange(100).reshape([10, 10])
print(arr)
print('-' * 33)
# min(数组,行1还是列0):求最小值
print(np.min(arr, 0))
print(np.min(arr, 1))
print('-' * 33)
# max(数组,行1还是列0):求最大值
print(np.max(arr, 0))
print(np.max(arr, 1))
print('-' * 33)
# median(数组,行1还是列0):求中位数
print(np.median(arr, 0))
print(np.median(arr, 1))
print('-' * 33)
# mean(数组,行1还是列0):求均值
print(np.mean(arr, 0))
print(np.mean(arr, 1))
print('-' * 33)
# std(数组,行1还是列0):求标准差
print(np.std(arr, 0))
print(np.std(arr, 1))
print('-' * 33)
# var(数组,行1还是列0):求方差
print(np.var(arr, 0))
print(np.var(arr, 1))
print('-' * 33)
24.数组间运算
数组与数运算,会让数与数组的每一个元素进行运算
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
arr = np.arange(1, 5)
print(arr)
print('-' * 33)
arr *= 3
print(arr)
[1 2 3 4]
---------------------------------
[ 3 6 9 12]
数组与数组运算
- 行列相同,则对应位置数分别运算
- 行列不同,要求只能是同等长度的一列或者一行进行计算,会重复拓展为相同行列进行计算
# coding:utf-8
# 作者:理想国真恵玩
import numpy as np
# 行列相同
arr1 = np.arange(10).reshape([2, 5])
arr2 = np.arange(10, 20).reshape([2, 5])
print(arr1)
print(arr2)
print(arr1 + arr2)
print('-' * 33)
# 行相同,列被扩展复制
arr3 = np.arange(10, 15)
print(arr1)
print(arr3)
print(arr1 + arr3)
print('-' * 33)
# 列相同,行被扩展复制
arr4 = np.arange(10, 12).reshape([2, 1])
print(arr1)
print(arr4)
print(arr1 + arr4)
[[0 1 2 3 4]
[5 6 7 8 9]]
[[10 11 12 13 14]
[15 16 17 18 19]]
[[10 12 14 16 18]
[20 22 24 26 28]]
---------------------------------
[[0 1 2 3 4]
[5 6 7 8 9]]
[10 11 12 13 14]
[[10 12 14 16 18]
[15 17 19 21 23]]
---------------------------------
[[0 1 2 3 4]
[5 6 7 8 9]]
[[10]
[11]]
[[10 11 12 13 14]
[16 17 18 19 20]]