Numpy模块(二)
Numpy(Numerical Python)是目前Python数值计算中最为重要的基础包。大多数计算包都提供了基于Numpy的科学函数功能,将Numpy的数组对象作为数据交换的通用语。
pip install numpy
import numpy as np
li = [1,2,3,4]
i = np.array(li)
print(i)
import numpy as np
i = np.arange(1,10,2)
注意,ndarray数组里面的每个元素均为相同类型.
例如下面这个列表,列表中有整数也有浮点数,然后转换为ndarray数组
li = [1,3.3,3,4.4]
i = np.array(li)
print(i)
输出结果:整个数组的数字都转为浮点数了
array([1. , 3.3, 3. , 4.4])
然后可以用dtype输出它的数据类型
print(i.dtype)
输出结果是:
float64
类型 | 类型代码 | 描述 |
---|---|---|
int8,uint8 | i1,u1 | 有符号和无符号的8数位整数 |
int16,uint16 | i2,u2 | 有符号和无符号的16数位整数 |
int32,uint32 | i4,u4 | 有符号和无符号的32数位整数 |
int64,uint64 | i8,u8 | 有符号和无符号的64数位整数 |
float16 | f2 | 半精度浮点数 |
float32 | f4 | 标准单精度浮点数 |
float64 | f8 | 标准双精度浮点数 |
bool | ? | 布尔值,存储True或False |
string_ | S | ASCII字符串类型,eg:‘S10’ |
unicode_ | U | Unicode类型,eg:‘U10’ |
在创建数组时,不管是array()还是arange()方法都有一个dtype参数,使用这个参数就可以指定数组的数据类型
li = [1,False,3,4.4]
i = np.array(li, dtype=np.int64)
print(i.dtype)
也可以通过类型代码实现:
li = [1,False,3,4.4]
i = np.array(li, dtype="i2")
print(i.dtype)
如果数据类型指定为布尔值的话,那么它实际就是将每个元素都进行一次布尔值运算
li = [1,2,3,4.4,0,-2,-3]
i = np.array(li, dtype=np.bool)
print(i)
# 输出结果:[ True True True True False True True]
已经创建好的数组,还可以用到astype()方法改变数据类型
li = [1,2,3,4.4,0,-2,-3]
i = np.array(li, dtype=np.bool)
i = i.astype(np.int32)
print(i.dtype)
使用ndim方法可以查看数组的维度
li = [1,2,3,4.4,0,-2,-3]
i = np.array(li, dtype=np.bool)
i.ndim
使用shape方法可以查看数组的形状
li = [1,2,3,4.4,0,-2,-3]
i = np.array(li, dtype=np.bool)
i.shape
# 返回结果: (7,)
创建二维数组其实也是使用array(),但是传入的列表格式为 “[[],[]]”,一个方括号包着两个方括号
li = [1,2,3,]
li2 = [4,5,6]
i = np.array([li,li2])
print(i)
print("数组的形状:",i.shape)
print("数组的维度:",i.ndim)
#返回结果
[[1 2 3]
[4 5 6]]
数组的形状: (2, 3)
数组的维度: 2
当两个列表不对称时,是无法构建出2维数组
比如下面的例子:
li = [1,2,3,]
li2 = [4,5]
i = np.array([li,li2])
print(i)
print("数组的形状:",i.shape)
print("数组的维度:",i.ndim)
# 返回结果
[list([1, 2, 3]) list([4, 5])]
数组的形状: (2,)
数组的维度: 1
创建三维的方式和二维的类似,但是二维只需要行、列即可构成,三维则还需要加上一个“坨”,每一坨代表一个二维数组。
代码中的格式如下:
i = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(i)
print("数组的形状:",i.shape)
print("数组的维度:",i.ndim)
# 返回结果
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
数组的形状: (2, 2, 3)
数组的维度: 3
与二维同理,如果每坨二维数组是不对称的,那么也是无法构建出三维数组
i = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9, 10], [10, 11, 12, 13]]])
print(i)
print("数组的形状:",i.shape)
print("数组的维度:",i.ndim)
# 返回结果
[[list([1, 2, 3]) list([4, 5, 6])]
[list([7, 8, 9, 10]) list([10, 11, 12, 13])]]
数组的形状: (2, 2)
数组的维度: 2
使用reshape()方法可以重塑数组。
从源码中可以看出,它传入的参数为shape,也就是要传入数组的形状。
arr = np.arange(6) # 生成一个一维数组
arr2 = arr.reshape(2,3) # 将1维转为2维
print(arr2)
print("数组的形状:",arr2.shape)
print("数组的维度:",arr2.ndim)
# 返回结果
[[0 1 2]
[3 4 5]]
数组的形状: (2, 3)
数组的维度: 2
arr3 = arr.reshape(1,2,3) # 将1维转3维
print(arr3)
print("数组的形状:",arr3.shape)
print("数组的维度:",arr3.ndim)
# 返回结果
arr3 = arr.reshape(1,2,3) # 将1维转3维
print(arr3)
print("数组的形状:",arr3.shape)
print("数组的维度:",arr3.ndim)
在源码中可以发现,reshape()方法还有一个order='C’的默认参数,尝试下改为order=‘F’,再看看结果
arr = np.arange(6) # 生成一个一维数组
arr2 = arr.reshape(2, 3, order="F") # 将1维转为2维
print(arr2)
print("数组的形状:", arr2.shape)
print("数组的维度:", arr2.ndim)
# 返回结果
[[0 2 4]
[1 3 5]]
数组的形状: (2, 3)
数组的维度: 2
arr3 = arr.reshape(1, 2, 3, order="F") # 将1维转3维
print(arr3)
print("数组的形状:", arr3.shape)
print("数组的维度:", arr3.ndim)
# 返回结果
[[[0 2 4]
[1 3 5]]]
数组的形状: (1, 2, 3)
数组的维度: 3
返回结果好像没有太大区别,再将两种结果拿出来对比:
# order="F"返回结果
[[0 2 4]
[1 3 5]]
数组的形状: (2, 3)
数组的维度: 2
# order="C"返回结果
[[0 1 2]
[3 4 5]]
数组的形状: (2, 3)
数组的维度: 2
在重塑三维的时候,“坨、行、列”这三个要素中有其中一个要素你不想算的时候,可以用-1代替,但只能代替1个数
例如下面的代码,我的数组总共有24个元素,我生成2坨、3行,但不知道几列,因此列的参数我可以放个-1代替。
arr4 = np.arange(24).reshape(2,3,-1)
print(arr4)
print("数组的形状:", arr4.shape)
print("数组的维度:", arr4.ndim)
# 返回结果
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
数组的形状: (2, 3, 4)
数组的维度: 3
基于目前学到的知识,用reshape()也可以实现多维转一维.
下面的例子是三维转一维
arr4 = np.arange(24).reshape(-1,3,4) # 目前arr4是一个三维数组
arr5 = arr4.reshape(arr4.shape[0]*arr4.shape[1]*arr4.shape[2]) # 三维转一维
print(arr5)
print("数组的形状:", arr5.shape)
print("数组的维度:", arr5.ndim)
arr5 = arr4.reshape(2*3*4)
# 等于
arr5 = arr4.reshape(24,)
不过多维转一维的方法肯定不止这一种,还有更加简便的方法,使用flatten()和ravel()
arr5.flatten()
arr5.ravel()
# 返回结果
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])
转置是沿着对角线将行与列对换.
使用transpose()和T都可以实现转置
arr6 = np.arange(10).reshape(2,5)
arr6.transpose()
# arr6.T
# 返回结果
array([[0, 5],
[1, 6],
[2, 7],
[3, 8],
[4, 9]])
换轴就是将行与列对换
arr6 = np.arange(10).reshape(2,5)
arr6.swapaxes(1, 0)
# 返回结果
array([[0, 5],
[1, 6],
[2, 7],
[3, 8],
[4, 9]])
函数名 | 描述 |
---|---|
array | 将输入数据转换为ndarray数组,自动推断数据类型,默认复制所有输入数据 |
asarray | 将输入数据转换为ndarray数组,但输入数据已经是ndarray则不再复制 |
arange | python内建函数range的数组版,返回一个数组 |
zeros | 根据给定形状和数据类型生成全0数组 |
ones | 根据给定形状和数据类型生成全1数组 |
empty | 根据给定形状和数据类型生成一个没有初始化数值的空数组 |
full | 根据给定形状和数据类型生成指定数值的数组 |
array和asarray的区别
data = np.arange(6)
arr1 = np.array(data) # 浅拷贝
arr2 = np.asarray(data) # 深拷贝
data[2] = 9 # 将第三个数值改为9
print(data) # 改变了
print(arr1) # 没变
print(arr2) # 改变了\
# 返回结果:
[0 1 9 3 4 5]
[0 1 2 3 4 5]
[0 1 9 3 4 5]
zeros、ones、empty、full的使用
arr1 = np.zeros((2,3)) # zeros
print(arr1)
# 返回结果
[[0. 0. 0.]
[0. 0. 0.]]
arr2 = np.ones((2,3))
print(arr2)
# 返回结果
[[1. 1. 1.]
[1. 1. 1.]]
arr3 = np.empty((2,3))
print(arr3)
# 返回结果
[[1. 1. 1.]
[1. 1. 1.]]
arr4 = np.full((2,3),3)
print(arr4)
#返回结果
[[3 3 3]
[3 3 3]]
zeros_like
ones_like
empty_like
full_like
数组与标量的算术操作会把计算参数传递给数组的每一个元素。
arr1 = np.arange(6).reshape(2,3)
print(arr1)
print(arr1+1)
# 返回结果
[[0 1 2]
[3 4 5]]
[[1 2 3]
[4 5 6]]
arr1 = np.arange(6).reshape(2,3)
print(arr1)
print(arr1*3)
#返回结果
[[0 1 2]
[3 4 5]]
[[ 0 3 6]
[ 9 12 15]]
两个等尺寸数组的算术操作实际上是逐元素操作。
arr2 = np.arange(6).reshape(2,3)
arr3 = np.arange(6).reshape(2,3)
arr2 + arr3
# 返回结果
[[0 1 2]
[3 4 5]]
[[0 1 2]
[3 4 5]]
[[ 0 2 4]
[ 6 8 10]]
广播机制规则:如果对于每个结尾维度(即从尾部开始的),轴长度都匹配或者长度都是1,两个二维数组就是可以进行广播的。之后,广播会在丢失的或者长度为1的轴上进行。
arr4 = np.arange(12).reshape(4,3) # 四行三列
arr5 = np.arange(3) # 一行三列 也就是行数不等,列数相等
arr6 = arr4 - arr5
print(arr6)
# 返回结果
[[0 0 0]
[3 3 3]
[6 6 6]
[9 9 9]]
arr7 = np.arange(12).reshape(4,3) # 四行三列
arr8 = np.arange(4).reshape(4,1) # 四行一列, 列相等,行不等
arr9 = arr7 - arr8
print(arr9)
# 返回结果
[[0 1 2]
[2 3 4]
[4 5 6]
[6 7 8]]