Loading [MathJax]/jax/output/CommonHTML/fonts/TeX/AMS-Regular.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Numpy与矩阵

Numpy与矩阵

作者头像
曼亚灿
发布于 2023-05-17 07:38:15
发布于 2023-05-17 07:38:15
1.4K00
代码可运行
举报
文章被收录于专栏:亚灿网志亚灿网志
运行总次数:0
代码可运行

原来线性代数这么有用!

请注意,本文编写于 980 天前,最后修改于 980 天前,其中某些信息可能已经过时。

Numpy优势

1 Numpy介绍

Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组

Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用Python要简洁的多。

Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器。

2 ndarray介绍

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NumPy provides an N-dimensional array type, the ndarray, 
which describes a collection of “items” of the same type.

NumPy提供了一个N维数组类型ndarray,它描述了相同类型的“items”的集合。

学生成绩数据

用ndarray进行存储:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np

# 创建ndarray
score = np.array(
[[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]])

score

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([[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]])

提问:

使用Python列表可以存储一维数组,通过列表的嵌套可以实现多维数组,那么为什么还需要使用Numpy的ndarray呢?

3 ndarray与Python原生list运算效率对比

在这里我们通过一段代码运行来体会到ndarray的好处

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import random
import time
import numpy as np
a = []
for i in range(100000000):
    a.append(random.random())

# 通过%time魔法方法, 查看当前行的代码运行一次所花费的时间
%time sum1=sum(a)

b=np.array(a)

%time sum2=np.sum(b)

其中第一个时间显示的是使用原生Python计算时间,第二个内容是使用numpy计算时间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CPU times: user 852 ms, sys: 262 ms, total: 1.11 s
Wall time: 1.13 s
CPU times: user 133 ms, sys: 653 µs, total: 133 ms
Wall time: 134 ms

从中我们看到ndarray的计算速度要快很多,节约了时间。

机器学习的最大特点就是大量的数据运算,那么如果没有一个快速的解决方案,那可能现在python也在机器学习领域达不到好的效果。

计算量大

Numpy专门针对ndarray的操作和运算进行了设计,所以数组的存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。

思考:

ndarray为什么可以这么快?

4 ndarray的优势

4.1 内存块风格

ndarray到底跟原生python列表有什么不同呢,请看一张图:

numpy内存地址

Python原生list中可以存放数字也可以存放字符串,但是numpy的list中只能存放同一种类型的元素。

从图中我们可以看出ndarray在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。

这是因为ndarray中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python原生list就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面Numpy的ndarray不及Python原生list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python原生list简单的多。

4.2 ndarray支持并行化运算(向量化运算)

numpy内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算

4.3 效率远高于纯Python代码

Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,所以,其效率远高于纯Python代码。

N维数组

1 ndarray的属性

数组属性反映了数组本身固有的信息。

属性名字

属性解释

ndarray.shape

数组维度的元组

ndarray.ndim

数组维数

ndarray.size

数组中的元素数量

ndarray.itemsize

一个数组元素的长度(字节)

ndarray.dtype

数组元素的类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np

score_data = np.array([[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_data.shape)
# 输出(8, 5),说明该多维数组为85print(score_data.ndim)
# 输出2,多维数组的维度

print(score_data.size)
# 输出40,多维数组中元素的数量

print(score_data.itemsize)
# 4 一个数组元素的长度(字节)

print(score_data.dtype)
# int32 数组元素的类型

2 ndarray的形状

首先创建一些数组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 创建不同形状的数组
>>> a = np.array([[1,2,3],[4,5,6]])
>>> b = np.array([1,2,3,4])
>>> c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])

分别打印出形状

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a.shape
>>> b.shape
>>> c.shape

(2, 3)  # 二维数组
(4,)    # 一维数组
(2, 2, 3) # 三维数组

如何理解数组的形状?

二维数组

三维数组

3 ndarray的类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> type(score.dtype)

<type 'numpy.dtype'>

dtype是numpy.dtype类型,先看看对于数组来说都有哪些类型

名称

描述

简写

np.bool

用一个字节存储的布尔类型(True或False)

'b'

np.int8

一个字节大小,-128 至 127

'i'

np.int16

整数,-32768 至 32767

'i2'

np.int32

整数,-2^31 至 2^32 -1

'i4'

np.int64

整数,-2^63 至 2^63 - 1

'i8'

np.uint8

无符号整数,0 至 255

'u'

np.uint16

无符号整数,0 至 65535

'u2'

np.uint32

无符号整数,0 至 2^32 - 1

'u4'

np.uint64

无符号整数,0 至 2^64 - 1

'u8'

np.float16

半精度浮点数:16位,正负号1位,指数5位,精度10位

'f2'

np.float32

单精度浮点数:32位,正负号1位,指数8位,精度23位

'f4'

np.float64

双精度浮点数:64位,正负号1位,指数11位,精度52位

'f8'

np.complex64

复数,分别用两个32位浮点数表示实部和虚部

'c8'

np.complex128

复数,分别用两个64位浮点数表示实部和虚部

'c16'

np.object_

python对象

'O'

np.string_

字符串

'S'

np.unicode_

unicode类型

'U'

创建数组的时候指定类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
>>> a.dtype
dtype('float32')

>>> arr = np.array(['python', 'tensorflow', 'scikit-learn', 'numpy'], dtype = np.string_)
>>> arr
array([b'python', b'tensorflow', b'scikit-learn', b'numpy'], dtype='|S12')
  • 注意:若不指定,整数默认int64,小数默认float64

基本操作

1 生成数组的方法

1.1 生成0和1的数组
  • np.ones(shape, dtype)
  • np.ones_like(a, dtype)
  • np.zeros(shape, dtype)
  • np.zeros_like(a, dtype)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: ones = np.ones([4,8])

In [3]: ones
Out[3]:
array([[1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.]])

In [4]: np.zeros_like(ones)
Out[4]:
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.],
       [0., 0., 0., 0., 0., 0., 0., 0.]])

2 从现有数组生成

1.2.1 生成方式
  • np.array(object, dtype)
  • np.asarray(a, dtype)
1.2.2 关于array和asarray的不同

两种方式的对比:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [5]: a = np.array([[1,2,3],[4,5,6]])

In [6]: a1 = np.array(a)  # 类似于深拷贝

In [7]: a2 = np.asarray(a)  # 类似于浅拷贝

In [8]: a[0, 0] = 100  # 对a中的[0, 0]位置元素赋值

In [9]: a1
Out[9]:
array([[1, 2, 3],  # a1未改变
       [4, 5, 6]])

In [10]: a2
Out[10]:
array([[100,   2,   3],  # a2改变
       [  4,   5,   6]])

3 生成固定范围的数组

1.3.1 np.linspace (start, stop, num, endpoint)
  • 创建等差数组 — 指定数量
  • 参数:
    • start:序列的起始值
    • stop:序列的终止值
    • num:要生成的等间隔样例数量,默认为50
    • endpoint:序列中是否包含stop值,默认为ture
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成等间隔的数组
np.linspace(0, 100, 11)

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([  0.,  10.,  20.,  30.,  40.,  50.,  60.,  70.,  80.,  90., 100.])
1.3.2 np.arange(start,stop, step, dtype)
  • 创建等差数组 — 指定步长
  • 参数
    • step:步长,默认值为1
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
np.arange(10, 50, 2)

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
       44, 46, 48])
1.3.3 np.logspace(start,stop, num)
  • 创建等比数列
  • 参数:
    • num:要生成的等比数列数量,默认为50
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成10^x
np.logspace(0, 2, 3)

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([  1.,  10., 100.])

4 生成随机数组

1.4.1 使用模块介绍
  • np.random模块
1.4.2 正态分布
一、基础概念复习:正态分布(理解)
a. 什么是正态分布

正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的方差,所以正态分布记作N(μ,σ )

正态分布函数图像

b. 正态分布的应用

生活、生产与科学实验中很多随机变量的概率分布都可以近似地用正态分布来描述。

c. 正态分布特点

μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布。

标准差如何来?

  • 方差:在概率论和统计方差衡量一组数据时离散程度的度量

其中M为平均值,n为数据总个数,σ 为标准差,σ ^2可以理解一个整体为方差。

  • 标准差与方差的意义:可以理解成数据的一个离散程度的衡量
二、正态分布创建方式

np.random.randn(d0, d1, …, dn)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
功能:从标准正态分布中返回一个或多个样本值

np.random.normal(*loc=0.0*, *scale=1.0*, *size=None*)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
loc:float

 此概率分布的均值(对应着整个分布的中心centre)

scale:float

 此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)

size:int or tuple of ints

 输出的shape,默认为None,只输出一个值

np.random.standard_normal(size=None)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
返回指定形状的标准正态分布的数组。
举例1:生成均值为1.75,标准差为1的正态分布数据,100000000个
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x1 = np.random.normal(1.75, 1, 100000000)

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([2.90646763, 1.46737886, 2.21799024, ..., 1.56047411, 1.87969135,
       0.9028096 ])
# 生成均匀分布的随机数
x1 = np.random.normal(1.75, 1, 100000000)

# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(20, 10), dpi=100)

# 2)绘制直方图
plt.hist(x1, 1000)

# 3)显示图像
plt.show()
1.4.2 均匀分布
  • np.random.rand(d0, d1, ..., dn)
    • 返回[0.0,1.0)内的一组均匀分布的数。
  • np.random.uniform(*low=0.0*, *high=1.0*, *size=None*)
    • 功能:从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开,即包含low,不包含high.
    • 参数介绍:
      • low: 采样下界,float类型,默认值为0;
      • high: 采样上界,float类型,默认值为1;
      • size: 输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出mnk个样本,缺省时输出1个值。
    • 返回值:ndarray类型,其形状和参数size中描述一致。
  • np.random.randint(low, high=None, size=None, dtype='l')
    • 从一个均匀分布中随机采样,生成一个整数或N维整数数组,
    • 取数范围:若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成均匀分布的随机数
x2 = np.random.uniform(-1, 1, 100000000)

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([ 0.22411206,  0.31414671,  0.85655613, ..., -0.92972446,
0.95985223,  0.23197723])

画图看分布状况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import matplotlib.pyplot as plt

# 生成均匀分布的随机数
x2 = np.random.uniform(-1, 1, 100000000)

# 画图看分布状况
# 1)创建画布
plt.figure(figsize=(10, 10), dpi=100)

# 2)绘制直方图
plt.hist(x=x2, bins=1000)  # x代表要使用的数据,bins表示要划分区间数

# 3)显示图像
plt.show()

均匀分布

数组的索引、切片

一维、二维、三维的数组如何索引?

  • 直接进行索引,切片
  • 对象[:, :] -- 先行后列

二维数组索引方式:

  • 举例:获取第一个股票的前3个交易日的涨跌幅数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 二维的数组,两个维度 
stock_change[0, 0:3]

返回结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
array([-0.03862668, -1.46128096, -0.75596237])
  • 三维数组索引方式:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 三维
a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
# 返回结果
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[12,  3, 34],
        [ 5,  6,  7]]])
# 索引、切片
>>> a1[0, 0, 1]   # 输出: 2

3 形状修改

3.1 ndarray.reshape(shape, order)
  • 返回一个具有相同数据域,但shape不一样的视图
  • 行、列不进行互换
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 在转换形状的时候,一定要注意数组的元素匹配
stock_change.reshape([5, 4])
stock_change.reshape([-1,10])  # 数组的形状被修改为: (2, 10), -1: 表示通过待计算
3.2 ndarray.resize(new_shape)
  • 修改数组本身的形状(需要保持元素个数前后相同)
  • 行、列不进行互换
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stock_change.resize([5, 4])

# 查看修改后结果
stock_change.shape
(5, 4)
3.3 ndarray.T
  • 数组的转置
  • 将数组的行、列进行互换
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stock_change.T.shape
(4, 5)

4 类型修改

4.1 ndarray.astype(type)
  • 返回修改了类型之后的数组
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stock_change.astype(np.int32)
4.2 ndarray.tostring([order])或者ndarray.tobytes([order])
  • 构造包含数组中原始数据字节的Python字节
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
arr.tostring()
4.3 jupyter输出太大可能导致崩溃问题【了解】

如果遇到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IOPub data rate exceeded.
    The notebook server will temporarily stop sending output
    to the client in order to avoid crashing it.
    To change this limit, set the config variable
    `--NotebookApp.iopub_data_rate_limit`.

这个问题是在jupyer当中对输出的字节数有限制,需要去修改配置文件

创建配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jupyter notebook --generate-config
vi ~/.jupyter/jupyter_notebook_config.py

取消注释,多增加

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
## (bytes/sec) Maximum rate at which messages can be sent on iopub before they
#  are limited.
c.NotebookApp.iopub_data_rate_limit = 10000000

但是不建议这样去修改,jupyter输出太大会崩溃

5 数组的去重

5.1 np.unique()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
>>> np.unique(temp)
array([1, 2, 3, 4, 5, 6])

运算

逻辑运算

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成10名同学,5门功课的数据
>>> score = np.random.randint(40, 100, (10, 5))

# 取出最后4名同学的成绩,用于逻辑判断
>>> test_score = score[6:, 0:5]

# 逻辑判断, 如果成绩大于60就标记为True 否则为False
>>> test_score > 60
array([[ True,  True,  True, False,  True],
       [ True,  True,  True, False,  True],
       [ True,  True, False, False,  True],
       [False,  True,  True,  True,  True]])

# BOOL赋值, 将满足条件的设置为指定的值-布尔索引
>>> test_score[test_score > 60] = 1
>>> test_score
array([[ 1,  1,  1, 52,  1],
       [ 1,  1,  1, 59,  1],
       [ 1,  1, 44, 44,  1],
       [59,  1,  1,  1,  1]])

通用判断函数

  • np.all()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 判断前两名同学的成绩[0:2, :]是否全及格
>>> np.all(score[0:2, :] > 60)
False
  • np.any()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 判断前两名同学的成绩[0:2, :]是否有大于90分的
>>> np.any(score[0:2, :] > 80)
True

np.where(三元运算符)

通过使用np.where能够进行更加复杂的运算

  • np.where()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 判断前四名学生,前四门课程中,成绩中大于60的置为1,否则为0
temp = score[:4, :4]
np.where(temp > 60, 1, 0)
  • 复合逻辑需要结合np.logical_and和np.logical_or使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 判断前四名学生,前四门课程中,成绩中大于60且小于90的换为1,否则为0
np.where(np.logical_and(temp > 60, temp < 90), 1, 0)

# 判断前四名学生,前四门课程中,成绩中大于90或小于60的换为1,否则为0
np.where(np.logical_or(temp > 90, temp < 60), 1, 0)

统计运算

如果想要知道学生成绩最大的分数,或者做小分数应该怎么做?

4.1 统计指标

数据挖掘/机器学习领域,统计指标的值也是我们分析问题的一种方式。常用的指标如下:

  • min(a, axis)
    • Return the minimum of an array or minimum along an axis.
  • max(a, axis])
    • Return the maximum of an array or maximum along an axis.
  • median(a, axis)(中位数)
    • Compute the median along the specified axis.
  • mean(a, axis, dtype)(均值)
    • Compute the arithmetic mean along the specified axis.
  • std(a, axis, dtype)(标准差)
    • Compute the standard deviation along the specified axis.
  • var(a, axis, dtype)(方差)
    • Compute the variance along the specified axis.
  • argmax()(最大值下标)
  • argmin()(最小值下标)

axis=1按行输出每行的最值,axis=0按列输出每列的最值。

4.2 案例:学生成绩统计运算

进行统计的时候,axis 轴的取值并不一定,Numpy中不同的API轴的值都不一样,在这里,axis 0代表列, axis 1代表行去进行统计

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 接下来对于前四名学生,进行一些统计运算
# 指定列 去统计
temp = score[:4, 0:5]
print("前四名学生,各科成绩的最大分:{}".format(np.max(temp, axis=0)))
print("前四名学生,各科成绩的最小分:{}".format(np.min(temp, axis=0)))
print("前四名学生,各科成绩波动情况:{}".format(np.std(temp, axis=0)))
print("前四名学生,各科成绩的平均分:{}".format(np.mean(temp, axis=0)))

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
前四名学生,各科成绩的最大分:[96 97 72 98 89]
前四名学生,各科成绩的最小分:[55 57 45 76 77]
前四名学生,各科成绩波动情况:[16.25576821 14.92271758 10.40432602  8.0311892   4.32290412]
前四名学生,各科成绩的平均分:[78.5  75.75 62.5  85.   82.25]

如果需要统计出某科最高分对应的是哪个同学?

  • np.argmax(temp, axis=)
  • np.argmin(temp, axis=)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print("前四名学生,各科成绩最高分对应的学生下标:{}".format(np.argmax(temp, axis=0)))

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
前四名学生,各科成绩最高分对应的学生下标:[0 2 0 0 1]

线性代数:矩阵

需要了解基础的矩阵知识!!!官方教材:《工程数学 · 线性代数(同济 · 第六版)》

学生成绩计算

计算公式:

矩阵运算:

矩阵乘法api

  • np.matmul
  • np.dot
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PS C:\Users\myxc> ipython
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.17.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import numpy as np

In [2]: a = np.array([[80, 86],
   ...: [82, 80],
   ...: [85, 78],
   ...: [90, 90],
   ...: [86, 82],
   ...: [82, 90],
   ...: [78, 80],
   ...: [92, 94]])

In [3]: b = np.array([[0.7], [0.3]])

In [4]: c = np.matmul(a, b)

In [5]: c
Out[5]:
array([[81.8],
       [81.4],
       [82.9],
       [90. ],
       [84.8],
       [84.4],
       [78.6],
       [92.6]])

In [6]: d = np.dot(a,b)

In [7]: d
Out[7]:
array([[81.8],
       [81.4],
       [82.9],
       [90. ],
       [84.8],
       [84.4],
       [78.6],
       [92.6]])

In [8]: c == d
Out[8]:
array([[ True],
       [ True],
       [ True],
       [ True],
       [ True],
       [ True],
       [ True],
       [ True]])

np.matmul和np.dot的区别:

二者都是矩阵乘法。 np.matmul中禁止矩阵与标量的乘法。 在矢量乘矢量的內积运算中,np.matmul与np.dot没有区别。对比如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: matrix_01 = np.array([[2, 3, 4, 3, 2, 5],
   ...:        [6, 7, 2, 3, 4, 2]])

In [3]: np.matmul(matrix_01, 10)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-84098b37479e> in <module>
----> 1 np.matmul(matrix_01, 10)

ValueError: matmul: Input operand 1 does not have enough dimensions (has 0, gufunc core with signature (n?,k),(k,m?)->(n?,m?) requires 1)

In [4]: np.dot(matrix_01, 10)
Out[4]:
array([[20, 30, 40, 30, 20, 50],
       [60, 70, 20, 30, 40, 20]])

数组间运算

数组与数的运算

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])

In [3]: arr + 1
Out[3]:
array([[2, 3, 4, 3, 2, 5],
       [6, 7, 2, 3, 4, 2]])

In [4]: arr / 2
Out[4]:
array([[0.5, 1. , 1.5, 1. , 0.5, 2. ],
       [2.5, 3. , 0.5, 1. , 1.5, 0.5]])

In [5]: a = [1, 2, 3, 4, 5]

In [6]: a * 3
Out[6]: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

对比Python原生list于数字的运算和numpy数组与数字的运算的差别。

数组与数组的运算

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
   ...: arr2 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])

In [3]: np.matmul(arr1, arr2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-c392db06761e> in <module>
----> 1 np.matmul(arr1, arr2)

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 6)

In [4]: arr3 = arr1.T

In [5]: np.matmul(arr1, arr3)
Out[5]:
array([[35, 31],
       [31, 76]])

矩阵的运算要符合规则!!!

广播机制

数组在进行矢量化运算时,要求数组的形状是相等的。当形状不相等的数组执行算术运算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的shape属性值一样,这样,就可以进行矢量化运算了。下面通过一个例子进行说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: arr1 = np.array([[0],[1],[2],[3]])
   ...: arr1.shape
Out[2]: (4, 1)

In [3]: arr2 = np.array([1,2,3])
   ...: arr2.shape
Out[3]: (3,)

In [4]: arr1+arr2
Out[4]:
array([[1, 2, 3],
       [2, 3, 4],
       [3, 4, 5],
       [4, 5, 6]])

上述代码中,数组arr1是4行1列,arr2是1行3列。这两个数组要进行相加,按照广播机制会对数组arr1和arr2都进行扩展,使得数组arr1和arr2都变成4行3列。

下面通过一张图来描述广播机制扩展数组的过程:

广播机制实现了时两个或两个以上数组的运算,即使这些数组的shape不是完全相同的,只需要满足如下任意一个条件即可。

  • 1.数组的某一维度等长。
  • 2.其中一个数组的某一维度为1 。

广播机制需要扩展维度小的数组,使得它与维度最大的数组的shape值相同,以便使用元素级函数或者运算符进行运算。

如果是下面这样,则不匹配:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A  (1d array): 10
B  (1d array): 12
A  (2d array):      2 x 1
B  (3d array):  8 x 4 x 3

思考:下面两个ndarray是否能够进行运算?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr2 = np.array([[1], [3]])

可以,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
In [1]: import numpy as np

In [2]: arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
   ...: arr2 = np.array([[1], [3]])

In [3]: arr1 + arr2
Out[3]:
array([[2, 3, 4, 3, 2, 5],
       [8, 9, 4, 5, 6, 4]])

----- END -----

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python:numpy模块最详细的教程
一、numpy简介 numpy官方文档:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750 numpy是Python的一种开源的数
Python学习者
2023/01/04
1.2K0
AI基础:Numpy简易入门
NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA 用其处理一些本来使用 C++,Fortran 或 Matlab 等所做的任务。
统计学家
2019/12/05
7050
numpy模块(对矩阵的处理,ndarray对象)
6.12自我总结 一.numpy模块 import numpy as np约定俗称要把他变成np 1.模块官方文档地址 https://docs.scipy.org/doc/numpy/referen
小小咸鱼YwY
2019/07/24
9550
numpy总结
df = pd.DataFrame({‘A’:[1,2,3],‘B’:[4,5,6],‘C’:[7,8,9]})
北山啦
2022/11/27
2.4K0
numpy总结
NumPy知识速记
由于NumPy提供了一个简单易用的C API,因此很容易将数据传递给由低级语言编写的外部库,外部库也能以NumPy数组的形式将数据返回给Python。这个功能使Python成为一种包装C/C++/Fortran历史代码库的选择,并使被包装库拥有一个动态的、易用的接口。
timerring
2023/05/07
1.1K0
NumPy知识速记
50个常用的 Numpy 函数详解
来源:CDA数据分析师 本文约7500字,建议阅读15分钟 在本文中,将介绍NumPy在数据科学中最重要和最有用的一些函数。 Numpy是python中最有用的工具之一。它可以有效地处理大容量数据。使用NumPy的最大原因之一是它有很多处理数组的函数。在本文中,将介绍NumPy在数据科学中最重要和最有用的一些函数。 创建数组 1、Array 它用于创建一维或多维数组 numpy.array(object, dtype=None, *, copy=True, order='K'
数据派THU
2023/05/18
9910
50个常用的 Numpy 函数详解
【深度学习】 NumPy详解(三):数组数学(元素、数组、矩阵级别的各种运算)
Python本身是一种伟大的通用编程语言,在一些流行的库(numpy,scipy,matplotlib)的帮助下,成为了科学计算的强大环境。本系列将介绍Python编程语言和使用Python进行科学计算的方法,主要包含以下内容:
Qomolangma
2024/07/29
1220
【深度学习】 NumPy详解(三):数组数学(元素、数组、矩阵级别的各种运算)
【深度学习】 NumPy详解(二):数组操作(索引和切片、形状操作、转置操作、拼接操作)
Python本身是一种伟大的通用编程语言,在一些流行的库(numpy,scipy,matplotlib)的帮助下,成为了科学计算的强大环境。本系列将介绍Python编程语言和使用Python进行科学计算的方法,主要包含以下内容:
Qomolangma
2024/07/29
1320
【深度学习】 NumPy详解(二):数组操作(索引和切片、形状操作、转置操作、拼接操作)
Numpy70题,由浅入深!
NumPy(Numerical Python)是Python的一个开源的数值计算扩展,它提供了高效的多维数组对象ndarray,以及大量的数学函数库,用于处理大型矩阵和数组运算。
皮大大
2024/06/04
2130
NumPy从入门到放弃
公众号本文地址:https://mp.weixin.qq.com/s/EocThNWhQlI2zeLcUApsQQ
愷龍
2024/08/09
1800
NumPy从入门到放弃
Numpy
You cannot protect yourself from sadness without protecting yourself from happiness.
小闫同学啊
2019/07/18
1K0
Numpy
【Python】numpy常用API整理汇总
linspace即线性插值:需要传递3个参数:开头,结尾,数量; 与之类似,还有指数线性插值np.logspace
zstar
2022/09/21
7470
Numpy
numpy(numerical Python) 是 Python 数值计算最重要的基础包,大多数提供科学计算的包都是用 NumPy 的数组为构建基础。 NumPy 可以用于数值计算的一个重要原因是因为他能处理大数组的数据:
爱编程的小明
2022/09/05
1.2K0
Numpy
numpy笔记_python numpy array
ndarray的可以对整块数据执行数学运算,语法与标量元素的元素的运算一致。 如:
全栈程序员站长
2022/09/20
6240
Numpy基础知识点汇总
1、概述 Numpy是高性能科学计算和数据分析的基础包,它的部分功能如下: 1)ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。 2)对整组数据进行快速运算的标准数学函数 3)用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 2、ndarray的创建 这一节,我们主要关注ndarray数组的创建,我们主要有以下几种方式: 数组转换 创建数组的最简单的方法就是使用array函数,将Python下的list转换为ndarray。 #通过数组创建一个ndarray data1
石晓文
2018/04/11
1.6K0
Numpy 笔记-基础篇
除非显式说明,np.array会尝试为新建的这个数组判断一个较为合适的数据类型。数据类型保存在特殊的dtype对象中。比如上面的两个例子中。我们有:
Ewdager
2020/07/14
4330
python的numpy入门简介
arr=np.array(data)    #将列表转为numpy.ndarray  np.array([2,4])
用户7886150
2021/01/07
1.4K0
Numpy 常用数据结构和清理函数
@toc Numpy 清理工具 Numpy常用数据结构 --- Numpy中常用的数据结构是ndarray格式 使用array函数创建,语法格式为array(列表或元组) 可以使用其他函数例如arange、linspace、zeros等创建 import numpy as np arr1 = np.array([-9, 7, 4, 3]) arr1 array([-9, 7, 4, 3]) type(arr1) # n维数组 numpy.ndarray arr1 = np.array([-9, 7,
ruochen
2021/05/12
3100
Numpy 常用数据结构和清理函数
我的机器学习numpy篇何为ndarray?ndarry创建生成正态分布ndarry属性修改形状ndarry运算ndarry切片矩阵转置聚合函数
前言: numpy是以矩阵为基础的数学计算模块,其基础为多维数组为ndarray 官方文档:(https://docs.scipy.org/doc/numpy/user/index.html) 何为ndarray? 一种由相同类型的元素组成的固定的多维数组。(注意黑体字) ndarry创建 代码如下 import numpy as np np.array([[1,2,3],[4,5,6]]) np.zeros((4,5)) np.ones((2,3,4)) np.random.randin
DC童生
2018/04/27
1K0
我的机器学习numpy篇何为ndarray?ndarry创建生成正态分布ndarry属性修改形状ndarry运算ndarry切片矩阵转置聚合函数
《利用Python进行数据分析·第2版》第4章 NumPy基础:数组和矢量计算4.1 NumPy的ndarray:一种多维数组对象4.2 通用函数:快速的元素级数组函数4.3 利用数组进行数据处理4.
NumPy(Numerical Python的简称)是Python数值计算最重要的基础包。大多数提供科学计算的包都是用NumPy的数组作为构建基础。 NumPy的部分功能如下: ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 线性代数、随机数生成以及傅里叶变换功能。 用于集成由C、C++、Fortran等语言编写的代码的A C API。 由于NumPy提供了一个
SeanCheney
2018/04/24
4.9K0
《利用Python进行数据分析·第2版》第4章 NumPy基础:数组和矢量计算4.1 NumPy的ndarray:一种多维数组对象4.2 通用函数:快速的元素级数组函数4.3 利用数组进行数据处理4.
推荐阅读
相关推荐
Python:numpy模块最详细的教程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文