2 NumPy库的基础操作

NumPy是一个专门用来进行数学计算的第三方库,对线性代数的支持较好。(Matlab与Python一较高下?期待...)

2.1 NumPy库安装和基本方法

安装好pip后,在cmd窗口输入:pip install numpy口令就好了。

Python没有数组类型,只能用列表这种类似数组的类型替代,但这一缺陷就可以有NumPy库来弥补。由NumPy官方手册介绍,NumPy库的主要对象是由同种类型数据构成的“多维数组”(理解成n维数组)。

在NumPy库里,axes 代表维度,length代表数组长度。支持多维度的数组对象被称为“ndarray”,通过numpy.ndarray来调用。不同于Python的工厂函数array.array,ndarray提供的方法更多且更实用。如下表提供的一些简单的方法

基本方法描述
ndarray.ndim返回一个int值,用来表示数组的维度
ndarray.size返回一个数组的总元素个数
ndarray.dtype一个描述数组里包含的数字所属类型的对象,可以是Python自带的数据类型也可以是NumPy库附加的数据类型
ndarray.shape显示这个数组的维度,返回一个元组。例:r行c列就返回(r,c)
ndarray.itemsize显示每个元素的比特位。例:float61是8(64/8)比特,complex32(32/8)是4比特,int16是4比特
ndarray.data一个包含实际元素的数组的缓冲区,查找元素操作可以使用索引序号,一般不会用到

2.2 创建一个数组

用列表或元组来创建一个二维数组

import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([(1, 2, 3), (4, 5, 6)])
c = np.arange(1, 7).reshape(2, 3)  # 利用迭代创建,arange和Python中range类似,reshape(行,列)

print(a)
print(b)
print(a == b)
print(c)
"""
结果好神奇:
[[1 2 3]
 [4 5 6]]
[[1 2 3]
 [4 5 6]]
[[ True  True  True]
 [ True  True  True]]
 [[1 2 3]
 [4 5 6]]
"""

2.2.1 reshape()

reshape()方法它可以重塑数组,格式为:

numpy.reshape(a, newshape, order=’C’)
a:array_like
    要重新形成的数组。
newshape:int或tuple的整数
    新的形状应该与原始形状兼容。如果是整数,则结果将是该长度的1-D数组。一个形状维度可以是-1。在这种情况下,从数组的长度和其余维度推断该值。
order(可选参数):{'C','F','A'}可选
    使用此索引顺序读取a的元素,并使用此索引顺序将元素放置到重新形成的数组中。
    C代表与C语言类似,行优先;
    F代表列优先
    注意,'C'和'F'选项不考虑底层数组的内存布局,而只是参考索引(行优先还是列优先而已)的顺序。
    'A'意味着在Fortran类索引顺序中读/写元素,如果a 是Fortran 在内存中连续的,否则为C样顺序。
关于reshape参数中-1的作用:数组新的shape属性应该要与原来的配套,如果等于-1的话,那么Numpy会根据剩下的维度计算出数组的另外一个newshape属性值。 
# 例子:把2行4列数组转换为4行2列
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
a = a.reshape(3, 2)
print(a)
"""
amazing!结果为:
[[1 2]
 [3 4]
 [5 6]]
"""
#关于参数为-1
d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
d = d.reshape(-1, 2)
print(d)  
"""
结果为:
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]
 [11 12]
 [13 14]
 [15 16]]
也就是说,我固定行(列),剩下的我不想算列(行)的个数,直接用-1,它会自动计算出多少列(行)
"""

2.2.2 arange()

arange()方法只是类似于range()方法迭代整型变量的情况,如果要迭代浮点数,需要使用linspace()方法

import numpy as np
a1 = np.arange(0, 53, 3).reshape(3, -1)  # 从0到53间隔3个迭代取数
print("a1:", a1)
b1 = np.linspace(0, 53, 3).reshape(3, -1)  # 从0到53,化为3段
print("b1:", b1)
c1 = np.linspace(0, 53, 18).reshape(3, -1)  # 只有linspace(0, 53, 18)这样写才能得到想要的数据
print("c1:", c1)
"""
结果为:
a1: [[ 0  3  6  9 12 15]
 [18 21 24 27 30 33]
 [36 39 42 45 48 51]]
b1: [[ 0. ]
 [26.5]
 [53. ]]
c1: [[ 0.          3.11764706  6.23529412  9.35294118 12.47058824 15.58823529]
 [18.70588235 21.82352941 24.94117647 28.05882353 31.17647059 34.29411765]
 [37.41176471 40.52941176 43.64705882 46.76470588 49.88235294 53.        ]]
"""

2.2.3 dtype

在生成矩阵时也可以使用dtype参数指定数据类型,dtype默认时整型,还可设置整型、浮点型和复数型等:

import numpy as np
a2 = np.array([[1, 2, 3], [4, 5, 6]])  # 默认整型
b2 = np.array([[1, 2, 3], [4, 5, 6]], dtype=float)  # 浮点型
c2 = np.array([[1, 2, 3], [4, 5, 6]], dtype=complex)  # 复数型
print(a2)
print(b2)
print(c2)
"""
结果为:
[[1 2 3]
 [4 5 6]]
[[1. 2. 3.]
 [4. 5. 6.]]
[[1.+0.j 2.+0.j 3.+0.j]
 [4.+0.j 5.+0.j 6.+0.j]]
"""

2.2.4 zeros()

zeros()方法生成“零矩阵”

"""
格式:np.zeros(shape, dtype=float, order=‘C’)
shape:1.传入一个数字,它将生成一个一维的向量;2.传入一个元组,它将生成以元组中各数字作为维度值的矩阵,比如zeros((2,4))->>>就是2行4列的零矩阵
dtype:在2.2.3节讲了,默认为float
order:可选参数,c代表与c语言类似,行优先;F代表列优先。
"""
import numpy as np
print(np.zeros(5))  # 一维
print(np.zeros((4, 4)))  # 4 x 4的矩阵
"""
结果为:
[0. 0. 0. 0. 0.]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
"""

2.2.5 ones()

用ones()方法生成“全1矩阵”

"""
np.ones(shape, dtype=float, order='C')
# shape:返回的数组的维度或形状(和zeros的shape属性类似)
# dtype:可选参数,返回的数组内数据的数据类型,默认是float
# order:可选参数,与C语言类似,C代表行优先,F代表列优先
"""
import numpy as np
print(np.ones(5))  # 一维
print(np.ones((4, 4)))  # 4 x 4的矩阵
"""
[1. 1. 1. 1. 1.]
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
"""

2.2.6 empty()

用empty()方法生成“随机浮点数矩阵”

"""
np.ones(shape, dtype=float, order='C')
# shape:返回的数组的维度或形状(和zeros的shape属性类似)
# dtype:可选参数,返回的数组内数据的数据类型
# order:可选参数,与C语言类似,C代表行优先,F代表列优先
"""
import numpy as np
print(np.empty(6))  # 一维
print(np.empty((4, 5)))  # 4 x 5的矩阵
"""
[0. 0. 0. 0. 0. 0.]
[[6.23042070e-307 1.42417221e-306 1.37962660e-306 6.23059726e-307
  1.95821439e-306]
 [8.01097889e-307 1.78020169e-306 7.56601165e-307 1.02359984e-306
  1.33510679e-306]
 [2.22522597e-306 1.33511018e-306 6.23057689e-307 1.02360120e-306
  8.45559303e-307]
 [8.06613465e-308 6.89810244e-307 1.22387550e-307 2.22522596e-306
  1.33511969e-306]]
"""

2.2.7 快速生成指数e大小

"""
格式为:
np.exp(n),n为指数,也就是e^n
"""
import numpy as np
print(np.exp(1))  # 2.718281828459045

2.2.8  快速生成圆周率大小

import numpy as np
print(np.pi)  # 3.141592653589793

当显示较长的矩阵时,会用省略号省去

import numpy as np
print(np.arange(10000).reshape(100, 100))
"""
[[   0    1    2 ...   97   98   99]
 [ 100  101  102 ...  197  198  199]
 [ 200  201  202 ...  297  298  299]
 ...
 [9700 9701 9702 ... 9797 9798 9799]
 [9800 9801 9802 ... 9897 9898 9899]
 [9900 9901 9902 ... 9997 9998 9999]]
"""

2.3 索引、切片和迭代

一维数组也是一维矩阵,同样也是一个列表,所以n维矩阵(n维数组)依然支持索引、切片和迭代操作。

2.3.1 索引和切片

一维示例(规则和列表的索引类似): 

import numpy as np
# 打印数组
a = np.arange(100)  # 创建一个一维数组
print(a)
"""
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 96 97 98 99]
"""
# 进行索引
print("索引操作:")
print(a[3])  # 找下标为3的元素
# 结果为:3
print("打印下标前10的元素:", end=' ')  # 用的是下标,而不是迭代器
for i in range(10):
    print(a[i], end=' ')
print()
# 结果为:0 1 2 3 4 5 6 7 8 9 
# 切片操作
print("正序号10到20:", a[10:21])  # 结果为[10 11 12 13 14 15 16 17 18 19 20] 
print("间隔为5,切片用逆序:", a[-10:-1:5])  # 结果为:[90 95]
a[:3] = 1
print("用切片操作先修改再打印:", a[:5])  # 结果为:[1 1 1 3 4]
# 迭代操作
print("迭代操作")
# 利用迭代器
for i in a:
    print(i)  # 输出到99

 多维矩阵中的每个维度都有独立的一组序号,所以二维矩阵可以用两个数进行索引;n维矩阵可以用n个数进行索引。

在举二维数组例子之前,学习一下fromfunction():生成矩阵用的函数,代码格式为:

numpy.fromfunction(function, shape, *, dtype=<class 'float'>, **kwargs)

参数作用:

  • function :callable该函数使用N个参数调用,其中N是的秩 shape。每个参数代表沿特定轴变化的数组坐标。例如,如果shape 为(2, 2),则参数将为(2, 2)array([[0, 0], [1, 1]]) 和 array([[0, 1], [0, 1]])
  • shape :(N,)个整数元组输出数组形式,它也确定传递给function的坐标数组的形状。
  • dtype:可选传递给function的坐标数组的数据类型。默认情况下dtype为float。
import numpy as np

def f1(x,y):
    return x

def f2(x,y):
    return y

def f3(x,y):
    return 2*x+y

a = np.fromfunction(f1, (5, 1), dtype=int)
print(a)
"""
结果为:
[[0]
 [1]
 [2]
 [3]
 [4]],可以发现:shape定义了输出矩阵的大小,在这个例子,体现了x为5行1列的矩阵(列向量)
"""
a1 = np.fromfunction(f1, (5, 5), dtype=int)
print(a1)
"""
结果为:
[[0 0 0 0 0]
 [1 1 1 1 1]
 [2 2 2 2 2]
 [3 3 3 3 3]
 [4 4 4 4 4]]
 在这个例子中,shape(5,5),第一个5表示为5行,第二个5表示为5列,
 而调用的f1函数,则是为了体现x为5行1列的矩阵(列向量)
"""
b = np.fromfunction(f2, (1, 5), dtype=int)
print(b)
# 结果为:[[0 1 2 3 4]],由此可以看出,函数中y表示为1行5列的矩阵(行向量)
b1 = np.fromfunction(f2, (5, 5), dtype=int)
print(b1)
"""
结果为:
[[0 1 2 3 4]
 [0 1 2 3 4]
 [0 1 2 3 4]
 [0 1 2 3 4]
 [0 1 2 3 4]]
"""
c = np.fromfunction(f3, (5, 5), dtype=int)
print(c)
"""
结果为:
[[ 0  1  2  3  4]
 [ 2  3  4  5  6]
 [ 4  5  6  7  8]
 [ 6  7  8  9 10]
 [ 8  9 10 11 12]]
 在这个例子中,函数中2*x表示控制元素的间隔为2,同理2*y也是控制元素的间隔为2
 所以n*x(y)表示间隔为n
"""

从这篇numpy函数fromfunction分析 - 啊哈彭 - 博客园文章学到的知识。

多维示例:在这里需要注意几个点:

  • 多维数组索引时:中括号[]中,行列用逗号(,)分开,比如二维矩阵b,我想找第三行第四列的元素,那就是b[3, 4]。(就类似数组的b[3][4])
  • 多维数组的切片时:1.第一维索引:中括号[]中,第一个冒号(:)前为索引的起始值,第一个冒号(:)后为索引的结束值(还是遵循取左不取右规则);2.第二维索引:接着逗号(,)后面时数组的第二维索引,数组各维的索引方式和第一维索引方式相同。比如b[1:4:2, ::2]1:4:2表示第一维的第1行(从0行开始),第3行(不取第4行),间隔为2;::2:表示对前面的起始和结束索引位置不做限制,间隔为2,是在第1维的基础上,取第0列和第2列;3.第三维索引:如果后面还有逗号,就是代表第三维,是在第二维得到的矩阵上进行操作,后续就是类似上述操作。4.≥3维的数组,可以通过'...'来简化操作,比如三维数组c,c[1, ...] 就等价于c[1, :, :],c[..., 1]等价于c[:, :, 1]。
import numpy as np
# 生成矩阵用的函数
def func_1(x, y):
    return 5 * x + y
# 生成并打印矩阵
b = np.fromfunction(func_1, (5, 4), dtype=int)
print(b)
# 多维数组索引
print("多维数组索引:")
print(b[3, 3])  # 可以理解为数组的b[3][3]
# 多维数组切片
print("多维数组切片:")
# 打印第0列
print(b[:, 0])
# 打印第0行
print(b[0, :])
# 逆序号,打印最后一行,以下两行作用相同
print(b[-1])
print(b[-1, :])
print(b[1: 4: 2])
print(b[1: 4: 2, ::2])
"""
结果为:
[[ 0  1  2  3]
 [ 5  6  7  8]
 [10 11 12 13]
 [15 16 17 18]
 [20 21 22 23]]
多维数组索引:
18
多维数组切片:
[ 0  5 10 15 20]
[0 1 2 3]
[20 21 22 23]
[20 21 22 23]
[[ 5  6  7  8]
 [15 16 17 18]]
[[ 5  7]
 [15 17]]
"""
# 生成一个三位数组
print("打印一个三维数组:")
c = np.arange(1, 19).reshape(2, 3, 3)  # 我理解三维数组是以长(x=2)宽(y=3)高(z=3)来理解的...(但是又隐约觉得不对,数学不好唉)
print(c)
print("示例一:")
print(c[1, :, :])
print(c[1, ...])
print("示例二")
print(c[..., 2])
print(c[:, :, 2])
"""
打印一个三维数组:
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]]

 [[10 11 12]
  [13 14 15]
  [16 17 18]]]
示例一:
[[10 11 12]
 [13 14 15]
 [16 17 18]]
[[10 11 12]
 [13 14 15]
 [16 17 18]]
示例二
[[ 3  6  9]
 [12 15 18]]
[[ 3  6  9]
 [12 15 18]]
"""

还有一些关于索引和切片的知识(比如布尔型切片等):

这篇文章有写->>>Numpy多维数组索引与切片详解 - 知乎

2.3.2 迭代

在学习迭代之前先学一下关于axis的理解:NumPy中axis的理解_zhwangye的博客-CSDN博客_numpy中的axis

可以学习到:axis为"[ ]"的层数,最外层为axis=0,往里一层便+1。

import numpy as np
print("打印一个三维数组:")
c = np.arange(1, 19).reshape(2, 3, 3)
print(c)
# 迭代一个维度(最外层)
print("迭代一个维度")
for firstAxis in c:
    print(firstAxis)
print("迭代两个维度")
for firstAxis in c:
    for secondAxis in firstAxis:
        print(secondAxis)
print("迭代三个维度方法一")
for firstAxis in c:
    for secondAxis in firstAxis:
        for thirdAxis in secondAxis:
            print(thirdAxis)
# 迭代三个维度还可以用flat方法
print("迭代三个维度方法二")
for element in c.flat:
    print(element)
# flat方法是将一个n位数字展开成一维后,再将结果打印出来,二默认遍历的是第一个维度(最外层的维度)

2.4 拼合、划分一个矩阵

全部写在一篇有点多分开写->>>传送门

2.5 深拷贝、浅拷贝与不拷贝

同上->>>传送门

Pyzhebzthon数据分析从小白到专家_百度百科这本书上学到的知识!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃头少女Emily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值