前言
在我python学到后期的时候看见了这个库Numpy。接着现在开始学习数据分析时又看见了这个名词,那么这个库很厉害吗?今天见分晓!
数据的维度
数据的维度,这里我就不想再提,直接上图吧,
(一维二维数据相关概念)[python之文件和数据格式学习笔记 | huan’s Notebook (yanghuanh1314.github.io)]
好,图上把该说的都说了,我无话可说。哈哈
在python里面数据是存放在列表中的,但是列表和数组有关系吗?在之前我就以为数组和列表是一个概念,带着这样的疑问我们继续往下看
Numpy的数组对象:ndarray
Numpy
Numpy是一个开源的python科学计算基础库,包含
- 一个强大的N维数组对象
ndarray
- 广播功能函数
- 整合C/C++/Fortran代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
Numpy是Scipy、Pandas等数据处理或科学计算库的基础
上面是照搬老师的ppt,就让来理解一下
ndarray是什么
看array是什么,也可以缩写为arr
数组的意思。
那nd
呢?我的理解就说一维(1D)、二维(2D)、三维(3D)····等等nD的意思。
这也就正好解释了Numpy是处理N维数组的库。
然后我们提到了数组与列表有什么区别
很明确一点,在基础的python里面不存在数组,一开始我也很纳闷,那列表不是数组的一种吗?现在看下来。
这是在Numpy官网上的发现的。我试着理解了一下。
简单的概括就说三点空间、长度与类型。如果学习过C语言,那么我想我说到这里应该已经明白了。
C语言定义一个数组要写两个参数:数组类型、数组大小。而且这个数组在这一个程序中是死的。后面不可以往里面添加元素。空间是死,除非你数组开大点,
int a[5]={1,2,3,4,5};
而python呢?首先可以看到不用定义长度,后续可以无限添加元素,其次也是我一直没试过的,原来里面的元素可以是整型、浮点型、字符,这就过分了。
>>> a = [1, 2, 3, 3.14, 0.56, 'a', 'b', 'c']
[1, 2, 3, 3.14, 0.56, 'a','b', 'c']
emmm,在C语言绝对不敢这么干。而且可以无限加元素。我也明白了为什么有人说python没有数组。
广播性
这也是Numpy的特性我想着是广播吗?这是一个机制,自动广播机制。
就是指不同形状的数组进行数值计算。
就是说有这么两组举例
import numpy as np
a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b
print (c)
[ 10 40 90 160]
先看着一个组,a与b的形状相同,则a[0]*b[0]
、a[1]*b[1]
、a[2]*b[2]
、 a[3]*b[3]
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
那这个呢,数组形状不一样欸。但是还是出现了结果,既然没有报错,好,其实这里就用到了广播机制。
以下是广播机制的规则,<菜鸟教程>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GAuS3fuq-1649593136531)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/广播机制.6nk6l4ltosc0.webp)]
我试着理解一下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fN3mnsV6-1649593136531)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/numpy广播机制.22ft93m28ti8.webp)]
可以看出来这是两个维度不一样的数组,我对他们进行求和,结果出来了。也知道这是numpy的广播机制,但是这是怎么做到的呢
其他
因为他的底层是用C/C++编写的,所以速度比原生python速度快,都知道编译型语言执行速度快于解释型语言的。
他就就是一个科学计算库,所以一些高级的数学计算想必是小菜一碟。
它是数据分析领域最基础的一个库,之前看过一篇文章,说是搭配Pandas库绝绝子。
Numpy的引用
这个很简单了。过分了。
import numpy as np
这里用的是别名np
也可以是其他,只不过np
`比较常用。
N维数组的对象:ndarray
python已有列表类型,为什么需要一个数组对象(类型)
数组对象可以去掉元素间运算所需要的循环,使一维向量更像单个数据
设置专门的数组对象,经过优化,可以提升这类应用的运算速度。
且在科学计算中,一个维度所有数据的类型往往相同
数组对象采用相同的数据类型,有助于节省运算和存储空间
这个怎么理解呢?
for
循环计算
a = [1,2,3,4]
b = [5,6,7,8]
c = []
for i in range(len(a)):
c.append(a[i]*b[i])
print(c)
[5, 12, 21, 32]
numpy运算
import numpy as np
a = np.array([1,2,3,4])
b = np.array([5,6,7,8])
c = a * b
print (c)
[ 5 12 21 32]
这样就离开了循环.
紧接着提到了效率
import numpy as np
my_arr = np.arange(1000000)
my_list = list(range(1000000))
In [10]: %time for _ in range(10): my_arr2 = my_arr * 2
Wall time: 13 ms
In [11]: %time for _ in range(10): my_list2 = [x * 2 for x in my_list]
Wall time: 716 ms
对比一下,让两个数组里的元素都×2,numpy执行速度比for循环快的多。
这样节省空间显而易见的呀,一个整数字节是4,那么5个20
数据往往相同,什么意思,做实验,你记录的数据肯定是同一个类型把,我们在学习概率部分,记录抛硬币正面的频率,他肯定是一个小数把,不可能是一个字符、整数。
而python的列表呢?
ndarray是一个多维数组对象,由两部分构成:
- 实际的数据
- 描述这些数据的元数据(数据维度,数据类型等)
ndarray数组一般要求所有元素类型相同(同质),数组下标从0开始
相同元素,列表与C语言数组对比后,就应该明白什么意思了把
两部分应该是说数据的内容和你这个数组的信息把,比如里面数组元素是什么类型,有几个、维度
import numpy as np
a = np.array([[1,2,3,4],
[5,6,7,8]])
a
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
np.array()
生成一个数组,其中ndarray在程序中的别名是array
print(a)
[[1 2 3 4]
[5 6 7 8]]
输出成[]
的形式,元素由空格分开
轴(axis):保存数据的维度;秩(rank):轴的数量
什么是轴,什么是秩?
andarray对象的属性
属性 | 说明 |
---|---|
.ndim | 秩,即轴的数量或维度的数量 |
.shape | ndarray对象的尺度,对于阵列,n行m列 |
.size | ndarray对象的个数,相当于.shape 中的n*m值 |
.dtype | ndarray对象的元素类型 |
.itemsize | ndarray对象中每个元素的大小,以字节为单位 |
andarray对象的属性
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
a.ndim
2
2个轴
a.shape
(4, 3)
通俗的说是4行3列的数组。
第一个维度有4个方向,第二个是维度有3个元素
a.size
12
4*3=12个元素
a.dtype
dtype('int32')
里面的元素类型是int32
a.itemsize
4
一个元素占4个字节
ndarray数组的元素类型
-
类型1:
数据类型 说明 bool
布尔类型, Ture
或False
intc
与C语言中的 int
类型一致,一般是int32
或int64
intp
用于索引的整数,与C语言中 ssize_t
一致,int32
或int64
int8
字节长度的整型,取值:[-128, 127] int16
16位长度的整数,取值:[-32768, 32767] int32
32位长度的整数,取值:[-231 , 231-1] int64
64位长度的整数,取值:[-263 , 263-1] -
类型2
数据类型 说明 uint8
8位无符号整数,取值:[0, 255] uint16
16位无符号整数,取值:[0, 65535] uint32
32位无符号整数,取值:[0, 232-1] uint64
32位无符号整数,取值:[0, 264-1] float16
16位半精度:1位符号位,5位指数,10位尾数 float32
32位半精度:1位符号位,8位指数,23位尾数 float64
264位半精度:1位符号位,11位指数,52位尾数 -
类型3
数据类型 说明 complex64
复数类型,实部和虚部都是32位浮点数 complex128` 复数类型,实部和虚部都是64位浮点数
什么是无符号整数?在C语言里面有这个概念,刚刚百度后发现说的就是非负数。在数学中存在一个负数,而这一类型与负数没有关系。其他的,说实话我对字节没有研究明白,还不能下过多结论。
ndarray为什么要支持这么多种类型元素?
对比:python语法仅支持整数、浮点数和复数三种类型
- 科学计算涉及数据较多,对存储和性能都要较高的要求。
- 对元素类型精细定义,有助于Numpy合理使用存储空间并优化性能
- 对元素类型精细定义,有助于程序员对程序规模合理评估
如果是说一个数组出现了很多类型的数据,第一眼看上去就是乱。里面什么都有。而且浪费空间。
然后因为是对数据进行处理,那么每天就会面对不同的数据。大家想想,数据只有整数和两位小数点的小数吗?不会吧。所以就出来了。
ndarray数组的创建
从python中的列表、元组等类型创建ndarray数组
x = np.array(list/tuple)
x = np.array(list/tuple, dtype=np.float32)
当np.array
不指定dtype
时,NumPy将根据数据情况关联一个dtype
类型
举例
import numpy as np
x = np.array([1,2,3,4,5]) # 列表
print(x)
[1 2 3 4 5]
import numpy as np
x = np.array((6,7,8,9,0)) # 元组
print(x)
[6 7 8 9 0]
import numpy as np
x = np.array([[1, 2, 3], (3.41), (4,5)]) # 列表和元组混合数据类型
print(x)
[list([1, 2, 3]) 3.41 (4, 5)]
但是这个会有提示,并不影响。
使用NumPy中函数创建ndarray数组
函数 | 说明 |
---|---|
np.arange(n) | 类似range() 函数,返回ndarray类型,元素从0到n-1 |
np.anes(shape) | 根据shape生成一个全1数组,shape是元组类型 |
np.zeros(shape) | 根据shape生成一个全0数组,shape是元组类型 |
np.full(shape, val) | 根据shape生成一个数组,每个元素值都是val |
np.eye(n) | 创建一个正方形n*n单位矩阵,对角线位1,其余为0 |
np.ones_like(a) | 根据数组a的形状生成一个全1数组 |
np.zeros_like(a) | 根据数组a的形状生成一个全0数组 |
np.full_like(a, val) | 根据数组a的形状生成一个数组,每个元素值都是val |
举例:
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
很像range()
np.ones((4, 6))
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.]], dtype=float16)
4行6列,全是1
np.zeros((4, 6))
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,
np.full((3, 5), 5)
array([[5, 5, 5, 5, 5],
[5, 5, 5, 5, 5],
[5, 5, 5, 5, 5]])
val
值,我输的5,全是5
np.eye(5)
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
是个正方形矩阵,对角线1.
x = np.array([[1,2,3],[4,5,6]])
print(x)
np.ones_like(x)
[[1 2 3]
[4 5 6]]
array([[1, 1, 1],
[1, 1, 1]])
x是一个二维数组,根据他的形状仿一个,全是1.
x = np.array([[1,2,3],[4,5,6]])
print(x)
np.zeros_like(x)
[[1 2 3]
[4 5 6]]
array([[0, 0, 0],
[0, 0, 0]])
全是0
npx = np.array([[1,2,3],[4,5,6]])
print(x)
np.full_like(x, 5)
[[1 2 3]
[4 5 6]]
array([[5, 5, 5],
[5, 5, 5]])
使用NumPy中其他函数创建ndarray数组
函数 | 说明 |
---|---|
np.linspace() | 根据起止数据等间距地填充数据,形成数组 |
np.concatenate() | 将两个或多个数组合并成一个新的数组 |
举例
np.linspace(1,10,4)
array([ 1., 4., 7., 10.])
他们是等间距的7-4=4-1
等差数列,1到10,4个元素,浮点数
np.linspace(1,7,4,endpoint=False)
array([1. , 2.5, 4. , 5.5])
endpoint
的参数如果是false,则不包括终止元素。我是这么想着,如果有false参数,是不是可以理解为保留两位小数
a = np.linspace(1,6,4)
b = np.linspace(1,6,4,endpoint=False)
print(a)
print(b)
[1. 2.66666667 4.33333333 6. ]
[1. 2.25 3.5 4.75]
像不像这个意思。
a = np.linspace(1,10,4)
b = np.linspace(1,10,4,endpoint=False)
np.concatenate((a,b))
array([ 1. , 4. , 7. , 10. , 1. , 3.25, 5.5 , 7.75])
合并
ndarray数组的变化
对于创建后的ndarray数组,可以对其进行维度变换和元素类型变换
a = np.ones((2,3,4), dtype=np.int3)
就是说数组的维度可以转换,一维变二维,二维变一维,高维转低维,反之,低维转高维。
ndarray数组的维度变换
方法 | 说明 |
---|---|
.reshape(shape) | 不改变数组元素,返回一个shape形状的数组,原数组不变 |
.resize(shape) | 与.reshape() 功能一致,但修改原数组 |
.swapaxes(ax1, ax2) | 将n个维度中两个维度进行调换 |
.flatten() | 对数组进行降维,返回折叠后的一维数组,原数组不变 |
import numpy as np
a = np.ones((2,3,4), dtype=np.int32)
a
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]]])
生成一个(2,3,4)形状的全一数组。
a.reshape((3,8))
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]])
根据a数组的内容进行维度转换,由(2,3,4)到(3,8)
a.resize((3,8))
a
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]])
他的功能与.reshape()
一致,但修改原数组
a.flatten()
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])
一下子把(2,3,4)的维度转换成一维数组。
print(a)
[[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]]
不改变原数组。
ndarray数组的类型变化
.astype(new_typ)
改变数组类型,但不改变数组内容。
a = np.ones((2,3,4), dtype=np.int32)
a
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]]])
b = a.astype(np.float16)
b
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.]]], dtype=float16)
ndarray数组向列表的转换、
ls = a.totlist()
a = np.full((2,3,4),25, dtype=np.int32)
a
array([[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]],
[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]]])
a.tolist()
[[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]],
[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]]]
转换成列表了。怎么看呢,前者的输出有个array提示,而后者输出没有提示
ndarray数组的操作
数组的索引与切片
- 索引:获取数组中特定位置元素的过程
- 切片:获取数组元素子集的过程
这个很简单,与python字符串、列表的一致,举一些例子
一维数组的切片与索引
与python的列表一致
import numpy as np
a = np.array([9,8,7,6,5])
a[2]
7
和以往类似,从0开始
a[1:4:2]
array([8, 6])
不含终止编号
多维数组的索引
规则是每一个维度一个索引值,逗号分隔
import numpy as np
a = np.arange(24).reshape(2,3,4)
a
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]]])
a[1,2,3]
23
a[0,1,2]
6
a[-1,-2,-3]
17
这个怎么说呢?从大往小缩。
多维数组的切片
- 选取一个维度用
:
- 每个维度切片方法与一维数组相同
- 每个维度可以使用步长跳跃切片。
import numpy as np
a = np.arange(24).reshape(2,3,4)
a
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]]])
a[:,1,-3]
array([ 5, 17])
a[:,1:3,:]
array([[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[16, 17, 18, 19],
[20, 21, 22, 23]]])
a[:,:,::2]
array([[[ 0, 2],
[ 4, 6],
[ 8, 10]],
[[12, 14],
[16, 18],
[20, 22]]])
ndarray数组的运算
数组与标量之间的运算
numpy一元函数
对ndarray中的数据执行元素级运算的函数
函数 | 说明 |
---|---|
np.abs(x) ,np.fabd(x) | 计算数组各元素的绝对值 |
np.sqrt(x) | 计算数组各元素的平方根 |
np.square(x) | 计算数组各元素的绝对值平方 |
np.ceil(x) , np.floor(x) | 计算数组各元素的ceiling值或floor值 |
np.log(x)``np.log10(x)``np.log2(x) | 计算数组各元素的自然对数,10底对数,2底对数 |
np.rint(x) | 计算数组各元素的四舍五入值 |
np.modf(x) | 计算数组各元素的小数和整数部分以两个独立数组形式返回 |
np.cos(x) ,np.cosh(x) ,np.sin(x) ,np.sinh(x) ,np.tan(x) ,np.tanh(x) , | 计算数组各元素的普通型和双曲线型三角函数 |
np.exp(x) | 计算数组各元素的指数值 |
np.sign(x) | 计算数组各元素的符号值,1(+),0,-1(-) |
举例
import numpy as np
x = np.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]]]))
x
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]]])
随意生成一个数组,进行操作
np.abs(x)
np.abs(x) # 求数组的绝对值
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]]])
可以看到有些元素是负数现在变成正数了。求绝对值。
np.sqrt(x)
np.sqrt(a) # 求a数组各元素平方根
array([[[0. , 1. , 1.41421356, 1.73205081],
[2. , 2.23606798, 2.44948974, 2.64575131],
[2.82842712, 3. , 3.16227766, 3.31662479]],
[[3.46410162, 3.60555128, 3.74165739, 3.87298335],
[4. , 4.12310563, 4.24264069, 4.35889894],
[4.47213595, 4.58257569, 4.69041576, 4.79583152]]])
np.square(x)
np.square(x) # 绝对值的平方
array([[[ 0, 1, 4, 9],
[ 16, 25, 36, 49],
[ 64, 81, 100, 121]],
[[144, 169, 196, 225],
[256, 289, 324, 361],
[400, 441, 484, 529]]], dtype=int32)
求平方
np.ceil(x)
, np.floor(x)
一开始我没有清楚ceiling
值和floor
值是什么
ceiling
值:向上取整floor
值:向下取整
什么意思呢,举例一个小数3.14,向上取整是4。向下取值是3,这里不是四舍五入。
import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8]]
arr = np.array(data)
arr
array([[1.2 , 2.5 , 3.14, 4.23],
[5.3 , 6.18, 7.4 , 8. ]])
生成一个浮点数型数组
np.ceil(arr)
array([[2., 3., 4., 5.],
[6., 7., 8., 8.]])
向上取整,1.2就是2,2.5就是3,等等。
np.floor(arr)
array([[1., 2., 3., 4.],
[5., 6., 7., 8.]])
向下取整,1.2就是1,2.5就是2,等等。
但会发现生成的都是浮点数。
np.log(x)
系列
这是个求对数的函数。
import numpy as np
a = np.arange(1,25).reshape(2,3,4)
a
array([[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]],
[[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]]])
重新生成一个数组,从1开始,0会有个提醒,不影响。
np.log(a)
array([[[0. , 0.69314718, 1.09861229, 1.38629436],
[1.60943791, 1.79175947, 1.94591015, 2.07944154],
[2.19722458, 2.30258509, 2.39789527, 2.48490665]],
[[2.56494936, 2.63905733, 2.7080502 , 2.77258872],
[2.83321334, 2.89037176, 2.94443898, 2.99573227],
[3.04452244, 3.09104245, 3.13549422, 3.17805383]]])
np.log10(a)
array([[[0. , 0.30103 , 0.47712125, 0.60205999],
[0.69897 , 0.77815125, 0.84509804, 0.90308999],
[0.95424251, 1. , 1.04139269, 1.07918125]],
[[1.11394335, 1.14612804, 1.17609126, 1.20411998],
[1.23044892, 1.25527251, 1.2787536 , 1.30103 ],
[1.32221929, 1.34242268, 1.36172784, 1.38021124]]])
np.log2(a)
array([[[0. , 1. , 1.5849625 , 2. ],
[2.32192809, 2.5849625 , 2.80735492, 3. ],
[3.169925 , 3.32192809, 3.45943162, 3.5849625 ]],
[[3.70043972, 3.80735492, 3.9068906 , 4. ],
[4.08746284, 4.169925 , 4.24792751, 4.32192809],
[4.39231742, 4.45943162, 4.52356196, 4.5849625 ]]])
np.rint(x)
import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8],[11.2, 4.5, 9, 8.9]]
arr = np.array(data)
arr
array([[ 1.2 , 2.5 , 3.14, 4.23],
[ 5.3 , 6.18, 7.4 , 8. ],
[11.2 , 4.5 , 9. , 8.9 ]])
np.rint(arr)
array([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[11., 4., 9., 9.]])
这是四舍五入,与上面的np.ceil(x)
, np.floor(x)
不一样。虽然都是小数变整数。都是浮点数形式。
np.modf(x)
np.modf(arr)
(array([[0.2 , 0.5 , 0.14, 0.23],
[0.3 , 0.18, 0.4 , 0. ],
[0.2 , 0.5 , 0. , 0.9 ]]),
array([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[11., 4., 9., 8.]]))
返回了两个数组,第一个数组存放小数部分,第二个数组是整数形式。
np.cos(x)
,np.cosh(x)
系列
import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8],[11.2, 4.5, 9, 8.9]]
arr = np.array(data)
arr
还用这个数组 。
np.cos(arr)
array([[ 0.36235775, -0.80114362, -0.99999873, -0.46389687],
[ 0.55437434, 0.99468112, 0.43854733, -0.14550003],
[ 0.20300486, -0.2107958 , -0.91113026, -0.86543521]])
np.cosh(arr)
array([[1.81065557e+00, 6.13228948e+00, 1.15735748e+01, 3.43658923e+01],
[1.00170901e+02, 2.41497013e+02, 8.17992521e+02, 1.49047916e+03],
[3.65652209e+04, 4.50141201e+01, 4.05154203e+03, 3.66598684e+03]])
cosX这些我不是很能理解。
np.exp(x)
import numpy as np
a = np.arange(24).reshape(2,3,4)
a
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]]])
np.exp(a)
array([[[1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01],
[5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03],
[2.98095799e+03, 8.10308393e+03, 2.20264658e+04, 5.98741417e+04]],
[[1.62754791e+05, 4.42413392e+05, 1.20260428e+06, 3.26901737e+06],
[8.88611052e+06, 2.41549528e+07, 6.56599691e+07, 1.78482301e+08],
[4.85165195e+08, 1.31881573e+09, 3.58491285e+09, 9.74480345e+09]]])
这是个指数形式,但我也对指数不是很了解
np.sign(x)
import numpy as np
x = np.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]]]))
x
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]]])
np.sign(x)
array([[[ 0, -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;0符号是0
numpy二元函数
函数 | 说明 |
---|---|
+ - * / ** | 两个数组个元素进行对应运算 |
np.maximum(x,y) , np.fmax() ,np.minimum(x) ,np.fmin(x) | 元素级的最大值/最小值计算 |
np.mod(x,y) | 元素级的模运算 |
np.copysign(x,y) | 将数组y中各元素值的符号赋值给数组x对应元素 |
> < >= <= == != | 算术比较,产生布尔型 |
上面写的有点乱,我现在重新创建两个数组。
import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8]]
x = np.arange(8).reshape(2,4)
y = np.array(data)
x
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
y
array([[1.2 , 2.5 , 3.14, 4.23],
[5.3 , 6.18, 7.4 , 8. ]])
一下试验都基于x,y两个数组,且两个数组形状一致。
数组运算
x + y
array([[ 1.2 , 3.5 , 5.14, 7.23],
[ 9.3 , 11.18, 13.4 , 15. ]])
x - y
array([[-1.2 , -1.5 , -1.14, -1.23],
[-1.3 , -1.18, -1.4 , -1. ]])
x * y
array([[ 0. , 2.5 , 6.28, 12.69],
[21.2 , 30.9 , 44.4 , 56. ]])
x / y
array([[0. , 0.4 , 0.63694268, 0.70921986],
[0.75471698, 0.80906149, 0.81081081, 0.875 ]])
x ** y
array([[0.00000000e+00, 1.00000000e+00, 8.81524093e+00, 1.04285255e+02],
[1.55209376e+03, 2.08753914e+04, 5.73217252e+05, 5.76480100e+06]])
这就是numpy的方便之处。不用for循环即可
np.maximum(x,y)
, np.fmax()
系列
np.maximum(x,y)
array([[1.2 , 2.5 , 3.14, 4.23],
[5.3 , 6.18, 7.4 , 8. ]])
np.minimum(x,y)
array([[0., 1., 2., 3.],
[4., 5., 6., 7.]])
这个应该是说数组各元素一一比较,x[0][0]
与y[0][0]
比较,0
与 -1.2
中0大。
np.mod(x,y)
np.mod(x,y)
array([[0., 1., 2., 3.],
[4., 5., 6., 7.]])
np.copysign(x,y)
data = [[-1.2, 2.5, -3.14, 4.23], [5.3, -6.18, 7.4, -8]]
z = np.array(data)
z # 这里需要修改一下数组,我定义成z
array([[-1.2 , 2.5 , -3.14, 4.23],
[ 5.3 , -6.18, 7.4 , -8. ]])
np.copysign(x,y)
array([[-0., 1., -2., 3.],
[ 4., -5., 6., -7.]])
因为y
和z
的数组符号都是整数,看不出。
可以看到z
数组的符号复制给了y数组。分别复制。
算术比较
x > y
array([[ True, False, True, False],
[False, True, False, True]])
x[0[0]
与y[0[0]
比较,0
>-1.2
对,返回True。一下都是类似。
x < y
array([[False, True, False, True],
[ True, False, True, False]])
x >= y
array([[ True, False, True, False],
[False, True, False, True]])
x <= y
array([[False, True, False, True],
[ True, False, True, False]])
x == y
array([[False, False, False, False],
[False, False, False, False]])
x != y
array([[ True, True, True, True],
[ True, True, True, True]])
补充
有些地方当时写的时候不是很理解,等返回来看时,又不知道怎么加上去
轴与秩
我先把这句话复制过来
轴(axis):保存数据的维度;秩(rank):轴的数量
我不是很明白。
我是这么想着,轴与秩等价?假设有个二维数组,数据的维度是2,轴是2,秩是轴的数量也是2?
轴
在知乎上看到一个大牛的解释,什么是轴,一维数组(空间)只有一个轴,一个数字确定一个位置。二维呢?直角坐标系。(x,y)两个轴确定一个位置;三维呢?(x,y,z)确定一个位置。四维、五维高维他是不是也是再说需要多少个轴。
用数学里的说一维画一个轴、二维两个,三维三个,以此类推?
维度与轴等价。几个维度几个轴。但是这样理解好像还有些欠妥。
我们举例子
-
二维数组
轴怎么表达呢?
我百度了需要numpy轴相关的定义,都是这样说的。
二维数组有两个轴,这个都没什么可说的。但是这两个轴个有序号,看上面的轴,
axis0
代表列,axis1
行。但我好奇这与保存数据的维度有什么关系呢?然后这样方便对这两条轴上的数据进行计算。我们看看。
这是个二维数组,axis0表示行,axis1是列、
arr2 = np.random.randint(0,9,size=(2,3)) arr2 # 二维
array([[2, 2, 4], [2, 5, 3]])
arr2.sum(axis=0) # 轴0上数据求和
array([4, 7, 7])
2+2=4,2+5=7,4+3=7
arr2.sum(axis=1) # 轴1上数据求和
array([ 8, 10])
2+2+4=8,2+5+3=10.
可是这与保存数据的维度有什么关系呢?
-
三维数组
同理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u85bSefa-1649593136533)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/三维数组轴解释.1khe9q1tnrsw.webp)]
arr3 = np.random.randint(0,9,size=(2,2,3)) arr3 # 三维
二维还是个平面,三维是个立体空间,不是很好理解。
arr3.sum(axis=0)
array([[13, 5, 11], [14, 2, 6]])
这个是怎么来着呢?
前后两个数相加。
arr3.sum(axis=1)
array([[15, 6, 5], [12, 1, 12]])
arr3.sum(axis=2)
array([[16, 10], [13, 12]])
一维数组比较特殊,我们不提,高维数组台抽象,现在不提。就看我们现在已经举例过的二维数组、三维数组来说。轴(axis)就是坐标系里的轴。二维有两个轴。三维三个、四维四个,n维n个。但是在numpy中,这个轴是由序列的,类似索引。从0开始。在我们的举例中使用来做计算的,这么说有点绕,
你指定那个轴,那么numpy就会顺着这条轴的方向进行操作。这么说会不会容易一些。好理解呢?
但我还是没想懂,这句话要说明什么。
轴(axis):保存数据的维度
秩
秩(rank):轴的数量
如果这么说的话,有几条轴,那么秩就是几。
import numpy as np
arr1 = np.random.randint(0,9,size=(5))
arr1.ndim # 一维
1
arr2 = np.random.randint(0,9,size=(2,3))
arr2.ndim # 二维
2
arr3 = np.random.randint(0,9,size=(2,2,3))
arr3.ndim # 三维
3
.ndim
:秩,即轴的数量或维度的数量
那我是不是可以认为这句是返回一个数组的维度。用上面的例子来说。1是一维、2是二维、3是三维。
维度
高维数组印象
我自以为我把维度学明白了。但是随着我敲代码的时候感觉我就是停留在了一维、二维、三维的空间里,更高维我怎么想不明白。
- 一维:一行数据
- 二维:一个表格
- 三维:空间
- 高维:???
我还是分别列出把
-
一维
import numpy as np arr1 = np.random.randint(0,9,size=(5)) arr1 # 一维
array([0, 1, 8, 0, 0])
很简单的一行数字。、
-
二维数组
arr2 = np.random.randint(0,9,size=(2,5)) arr2 # 二维
array([[3, 8, 0, 3, 7], [4, 8, 4, 6, 2]])
可以看作由两个一维数组构成。
-
三维数组
arr3 = np.random.randint(0,9,size=(3,2,5)) arr3 # 三维
array([[[6, 4, 5, 0, 4], [7, 0, 4, 6, 0]], [[1, 1, 2, 4, 3], [4, 8, 0, 5, 6]], [[2, 8, 6, 8, 3], [6, 5, 7, 0, 1]]])
可以看作是由三个二维数组构成,每个二维数组又是由两个一维数组构成。
-
四维数组
arr4 = np.random.randint(0,9,size=(3,2,3,5)) arr4 # 四维
array([[[[7, 5, 8, 4, 1], [6, 1, 1, 6, 1], [4, 6, 8, 2, 5]], [[8, 4, 4, 8, 6], [7, 1, 8, 7, 7], [2, 4, 2, 3, 4]]], [[[6, 7, 7, 6, 5], [5, 2, 6, 5, 4], [8, 3, 4, 5, 3]], [[2, 1, 7, 0, 3], [3, 5, 5, 4, 5], [8, 6, 1, 1 1]]], [[[6, 7, 5, 7, 0], [8, 5, 1, 6, 8], [8, 7, 8, 8, 7]], [[7, 1, 2, 3, 6], [4, 1, 2, 1, 0], [5, 8, 2, 1, 8]]]])
为什么这个四维数组会这样打印呢,不管了。我们要分析一些。由三个三维数组构成,每个三维数组又是由两个二维数组构成,而这次不一样了。每个二维数组都是由三个一维数组构成
他的构成成分、
-
五维数组
import numpy as np arr = np.random.randint(0,9,size=(2,2,3,2,5)) arr
生成一个五维数组,为了节省空间,这里就不展示了。
这就是五维数组的构成。随之我发现了一个规律。
-
高维数组
import numpy as np arr = np.random.randint(0,9,size=(2,2,3,2,3,2,4,5)) arr
arr.ndim
8
这是一个8维数组。
他的构成是最外层是两个七维数组、一个七维数组由两个六维数组构成、一个六维数组由三个五维数组构成、一个五维数组由两个四维数组构成、一个四维数组由三个三维数组构成,一个三维数组由两个二维数组构成,一个二维数组由四个一维数组构成,一个一维数组有5个元素。
这个形状的组成。
突然想到了什么,n维数组是在
n-1
的数组基础上形成的,三维数组是在二维数组上形成的,二维数组是在一维数组上形成的。arr.shape
(2, 2, 3, 2, 3, 2, 4, 5)
但是说了这么多我想说明什么?我也不知道,快8000字了。还是想说有一个高维数组的空间印象,我现在最高停留在三维数组。好吧,这里结束。希望以后处理不到高维数组。嘻嘻。
高维数组轴计算
想出来都难了,还考虑计算,我看了一篇文章,对数组进行降维。什么意思呢?
import numpy as np
arr = np.array([[[2, 6, 1],[3, 7, 7]],[[8, 6, 1],[2, 1, 4]]])
arr
array([[[2, 6, 1],
[3, 7, 7]],
[[8, 6, 1],
[2, 1, 4]]])
对这么一个三维数组进行降维,我先跟着教程走一遍,之后再用四维数组举例,
先把最内层的数组看成一个整体,因此如下
A = np.array([2,6,1]) # 对内部数组分别创建一个新的数组
B = np.array([3,7,7])
C = np.array([8,6,1])
D = np.array([2,1,4])
arr_new = np.array([[A, B],[C, D]])
arr_new
array([[[2, 6, 1],
[3, 7, 7]],
[[8, 6, 1],
[2, 1, 4]]])
这时就是一个二维数组。
看到这张图,我直接咔咔做运算
arr_new.sum(axis=0)
array([[10, 12, 2],
[ 5, 8, 11]])
A + C
array([10, 12, 2])
B + D
array([ 5, 8, 11])
想要说明什么,最开始的举例是数与数相加求和,而这里是数组与数组相加求和。要不你往前翻翻看看。
arr_new.sum(axis=1)
array([[ 5, 13, 8],
[10, 7, 5]])
A + B
array([ 5, 13, 8])
C + D
array([10, 7, 5])
但是三维数组有三个轴,所以axis2是什么呢?首先要说明一点,三维数组转换成二维数组,还是有第三个轴的。
arr_new.sum(axis=2)
array([[ 9, 17],
[15, 7]])
分别对每一个一维数组求和。
举例
这个高维数组我现在也没有整明白,先不做了吧,有点费时间,我想在数据处理分析中用到最多的应该是二维数组吧,处理表格等等。
广播性
前面浅提了一下广播性,我还是没明白。
先搞明白广播机制的触发条件是两个或多个数组做运算,并且他们的形状都不相同,此刻触发机制。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMxDPn5p-1649593136535)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/广播机制.6nk6l4ltosc0.webp)]
这个定义有点绕,官网也有介绍,我也不是很明白。我们先举例子。
二维数组 + 一维数组
import numpy as np
arr1 = np.random.randint(0,9,size=(2,3))
arr2 = np.random.randint(0,9,size=(3))
arr1
array([[4, 4, 5],
[0, 8, 6]])
a1 = []
arr2
array([3, 4, 2])
arr1 + arr2
array([[ 7, 8, 7],
[ 3, 12, 8]])
这个怎么看呢,他把一维数组无形之中转换成了二维数组,以高维看齐。
它是怎么转换着呢?复制。
把[3,4,2]
复制一遍,一维变二维。`arr1 = [[3,4,2],[3,4,2]]
在这里我想打印一下他们的形状
arr1.shape
(2, 3)
arr2.shape
(3,)
我们在写几组例子,分析|
三维数组 + 二维数组
arr3 = np.random.randint(0,9,size=(2,2,3))
arr4 = np.random.randint(0,9,size=(2,3))
arr3
array([[[7, 8, 4],
[6, 5, 7]],
[[0, 8, 8],
[1, 2, 7]]])
arr4
array([[4, 5, 6],
[6, 3, 8]])
arr3 + arr4
array([[[11, 13, 10],
[12, 8, 15]],
[[ 4, 13, 14],
[ 7, 5, 15]]])
这个二维数组发生了改变
紧接着打印形状
arr3.shape
(2, 2, 3)
arr4.shape
(2, 3)
三维数组 + 一维数组
arr5 = np.random.randint(0,9,size=(2,2,3))
arr6 = np.random.randint(0,9,size=(3))
arr5
array([[[5, 3, 3],
[0, 0, 1]],
[[3, 6, 4],
[7, 1, 1]]])
arr6
array([7, 7, 1])
arr5 + arr6
array([[[12, 10, 4],
[ 7, 7, 2]],
[[10, 13, 5],
[14, 8, 2]]])
这个一维数组被转换
打印形状
arr5.shape
(2, 2, 3)
arr6.shape
(3,)
不成功的例子
arr7 = np.random.randint(0,9,size=(2,2,3))
arr8 = np.random.randint(0,9,size=(4))
arr7 + arr8
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22492/1830531957.py in <module>
----> 1 arr7 + arr8
ValueError: operands could not be broadcast together with shapes (2,2,3) (4,)
arr9 = np.random.randint(0,9,size=(2,3))
arr10 = np.random.randint(0,9,size=(4))
arr9 + arr10
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22492/2797848224.py in <module>
----> 1 arr9 + arr10
ValueError: operands could not be broadcast together with shapes (2,3) (4,)
arr11 = np.random.randint(0,9,size=(2,3,5))
arr12 = np.random.randint(0,9,size=(4,5))
arr11 + arr12
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22492/958249982.py in <module>
----> 1 arr11 + arr12
ValueError: operands could not be broadcast together with shapes (2,3,5) (4,5)
为社么不成功呢,一开始还好好着
广播机制总结
不成功,还是和他们的形状有关系。在这里也存在的一些规则。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nupyn7eu-1649593136537)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/image.292l5rz5n9jw.webp)]
这里提出一个名词,尾随尺寸:就是说这个形状的最后一个值,尾部值
对比这两个数组的形状,不一样,就看他们的形状的尾部值,当尾部值相等或者其中一个是1或者0时,触发机制。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmId1kkH-1649593136537)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220410195402307.png)]
用通俗的话说,我是这么理解的np.shape
返回一个数组的形状,就开始对比这两个数组的形状。从右往左作比较(最后一个数)如果相等,那就往前走,不等,需要判断是0或者是1,是的话那就与最大数相等,再往前走。否则返回一个错误
ValueError: operands could not be broadcast together
就是这样。
总结
这一章笔记,对numpy有了一个大致的了解。
数据的维度,是什么。一维数据就是一个列表,二维数据是个表格。高维数组。
numpy是什么?一个强大的科学计算库,数组对象是ndarray。怎么说呢。一开始我以为很难,因为数据分析就很难。我现在明白了就是说对数组进行计算。不学习numpy也可以,for循环,但是速度慢啊。既然说到了速度,为什么说快呢,它的底层是C/C++/Fortran等编写的。所以快。
了解了numpy是什么后,就开始对数组进行操作、创建、运算、变化等等,学习了很多的函数。现在想起来好像就记住了一两个。但是没关系,我可以以后Ctrl+F
呀。
然后就是补充的内容,轴与秩、维度、广播机制。我感觉我弄明白了一点,有感觉还是一头雾水。但是这也是刚刚学习吧,吧一些函数、概念什么的弄明白,之后在实践中慢慢理解吧。
我觉学习得维度还得是靠想像,我一开始觉得我对数据的维度学的很明白。,慢慢着我对高维有点难以理解,一维是先,二维是平面、三维是空间。那四维呢,
好了,我的学习笔记到此结束。
里面肯定有许许多多的bug,欢迎大家指出!毕竟这样成长更快。
也感谢大家可以看到这样,如果帮到了你,是我的荣幸。
谢谢大家!
~\AppData\Local\Temp/ipykernel_22492/1830531957.py in <module>
----> 1 arr7 + arr8
ValueError: operands could not be broadcast together with shapes (2,2,3) (4,)
arr9 = np.random.randint(0,9,size=(2,3))
arr10 = np.random.randint(0,9,size=(4))
arr9 + arr10
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22492/2797848224.py in <module>
----> 1 arr9 + arr10
ValueError: operands could not be broadcast together with shapes (2,3) (4,)
arr11 = np.random.randint(0,9,size=(2,3,5))
arr12 = np.random.randint(0,9,size=(4,5))
arr11 + arr12
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22492/958249982.py in <module>
----> 1 arr11 + arr12
ValueError: operands could not be broadcast together with shapes (2,3,5) (4,5)
为社么不成功呢,一开始还好好着
广播机制总结
不成功,还是和他们的形状有关系。在这里也存在的一些规则。
[外链图片转存中…(img-ZIBc8r0Z-1649593136537)]
[外链图片转存中…(img-Nupyn7eu-1649593136537)]
这里提出一个名词,尾随尺寸:就是说这个形状的最后一个值,尾部值
对比这两个数组的形状,不一样,就看他们的形状的尾部值,当尾部值相等或者其中一个是1或者0时,触发机制。
[外链图片转存中…(img-5TaKRBTW-1649593136537)]
[外链图片转存中…(img-CmId1kkH-1649593136537)]
[外链图片转存中…(img-1Jcnkf3L-1649593136538)]
用通俗的话说,我是这么理解的np.shape
返回一个数组的形状,就开始对比这两个数组的形状。从右往左作比较(最后一个数)如果相等,那就往前走,不等,需要判断是0或者是1,是的话那就与最大数相等,再往前走。否则返回一个错误
ValueError: operands could not be broadcast together
就是这样。
总结
这一章笔记,对numpy有了一个大致的了解。
数据的维度,是什么。一维数据就是一个列表,二维数据是个表格。高维数组。
numpy是什么?一个强大的科学计算库,数组对象是ndarray。怎么说呢。一开始我以为很难,因为数据分析就很难。我现在明白了就是说对数组进行计算。不学习numpy也可以,for循环,但是速度慢啊。既然说到了速度,为什么说快呢,它的底层是C/C++/Fortran等编写的。所以快。
了解了numpy是什么后,就开始对数组进行操作、创建、运算、变化等等,学习了很多的函数。现在想起来好像就记住了一两个。但是没关系,我可以以后Ctrl+F
呀。
然后就是补充的内容,轴与秩、维度、广播机制。我感觉我弄明白了一点,有感觉还是一头雾水。但是这也是刚刚学习吧,吧一些函数、概念什么的弄明白,之后在实践中慢慢理解吧。
我觉学习得维度还得是靠想像,我一开始觉得我对数据的维度学的很明白。,慢慢着我对高维有点难以理解,一维是先,二维是平面、三维是空间。那四维呢,
好了,我的学习笔记到此结束。
里面肯定有许许多多的bug,欢迎大家指出!毕竟这样成长更快。
也感谢大家可以看到这样,如果帮到了你,是我的荣幸。
谢谢大家!