[学习笔记]-Python中NumPy基础

NumPy是一个高性能的科学计算和数据分析基础包,在现在的数据分析领域有很多应用,这得益于NumPy的多维数组对象、线性代数、傅里叶变换和随机数等强大功能。

一、多维数组

1. 创建多维数组
使用NumPy中的array
1
2
import numpy as np
print(np.array([[1,2,3], [4,5,6]]))

在运行后,输出的内容如下:

1
2
[[1, 2, 3]
[4, 5, 6]]

其方法是直接在array中传入一个带有参数的列表,这个列表会被转换成数组,创建更高维数组的方法和一维数组差不多,只不过变成了把一个嵌套的列表作为参数传递给array。

当然,创建高维数组还有很多其他方式,并不局限于在以上实例中使用的方法。但是,直接将一串数字作为参数传递给array来创建一个数组是不合法的,如果我们传递给array的参数是列表,则列表会被array当作一个不定长参数进行处理,但若传递给array的参数是一串数字,则会被array当作多个参数而不能处理。

有时我们需要创建一个临时的数组,以方便之后对数据进行存储。对于这种情况,在NumPy中有多种方法可以创建维度指定的临时数组,如下所示。

(1)使用NumPy中的onse可以创建维度指定且元素全为1的数组。
1
2
import numpy as np
print(np.ones([2,3]) )#创建全1的数组

在运行后,输出的内容如下

1
2
[[ 1.,  1.,  1.]
[ 1., 1., 1.]]

使用onse生成了一个元素全为1且维度为(2,3)的数组,传递给onse的参数是一个列表,如果使用元组,则也能够达到一样的效果。这样,一个可用来进行临时数据存放的数组就创建完成了,之后若要更新这个数组中的元素,则直接进行覆盖就可以了。

(2)使用NumPy中的zeros可以创建维度指定且元素全为0的数组。
(3)使用NumPy中的empty可以创建维度指定且元素全为随机数的数组。
2.多维数组的常用属性
(1)ndim:返回统计的数组维数,即维度的数量。
(2)shape:返回数组的维度值。

对返回的结果使用一个数据类型为整型的元组来表示,比如一个二维数组返回的结果为(n,m),那么n和m表示数组中对应维度的数据的长度。如果使用shape输出的是矩阵的维度,那么在输出的(n,m)中,n表示矩阵的行,m表示矩阵的列。

1
2
3
4
import numpy as np
a =np.matrix([[2,3], [3,4]]) #创建矩阵
print(a)
print(a.shape)

在运行后,输出的内容如下:

1
2
3
[[2 3]
[3 4]]
(2, 2)

以上代码中使用了np.matrix来搭建矩阵,搭建矩阵需要传递的参数和使用array搭建数组时传递参数的方法一样

(3)size:返回要统计的数组中的元素的总数量。
(4)dtype:返回数组中的元素的数据类型。

不过其显示的数据类型和我们之前定义的变量的数据类型名有所区别,因为这些数据类型都是使用NumPy进行定义的,而在NumPy中表示数据类型使用的是numpy.int32、numpy.int16和numpy.float64这类格式的名字。

(5)itemsize:返回数组中每个元素的字节大小。

比如元素的dtype是float64,那么其itemsize是8,计算方法为8=64/8;如果元素的dtype是complex32,那么其itemsize是4,计算方法为4=32/8,其他dtype的计算方法以此类推。

1
2
3
import numpy as np
a =np.ones([2,3], dtype=np.int32) #创建全1的数组
print(a.itemsize)

在运行后,输出的内容如下:

1
4
3.数组的打印

数组可以通过print进行打印输出,打印出的数组和嵌套的列表很相似。还有一种情况,在数组中的元素太多时,若全部进行打印输出,则会占用大面积的显示空间,而且不易查看,所以在打印输出元素过多的数组时,输出显示的内容会自动跳过中间的部分,只打印首尾的一小部分,对中间的部分用省略号(…)来代替。

1
2
3
import numpy as np
a =np.arange(2000) #创建有2000个元素的数组
print(a)

在运行后,输出的内容如下

1
[   0    1    2 ... 1997 1998 1999]

二、 数组的算术运算

1
2
3
4
5
6
7
8
import numpy as np
a =np.array([1,2,3])
b =np.array([4,5,6])

print("a - b =", a-b) #打印a-b的结果
print("a + b =", a+b) #打印a+b的结果
print("a / b =", a/b) #打印a/b的结果
print("a * b =", a*b) #打印a*b的结果

在运行后,输出的内容如下

1
2
3
4
a - b =[-3-3-3]
a + b =[5 7 9]
a / b =[ 0.25 0.4 0.5 ]
a * b =[ 4 10 18]

虽然数组在构造上类似于矩阵,但是其运算和矩阵运算存在诸多不同:首先,矩阵是不存在除法运算的,但是数组能够进行除法运算;其次,数组的乘法运算机制是通过将位置对应的元素相乘来完成的,和矩阵的乘法运算机制不同。

下面来看看如何通过数组实现矩阵乘法运算:

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
a =np.array([1,2,3])
b =np.array([4,5,6])

print("a * b =", a*b) #打印a*b的结果

c =a.dot(b)
print("Matrix1: a * b =", c) #打印a*b的结果

d =np.dot(a, b)
print("Matrix2: a * b =", c) #打印a*b的结果

以上代码中使用了两种方法来实现矩阵的乘法运算,其计算结果是一样的。数组和矩阵的算术运算还有一个较大的不同点,就是数组可以直接和标量进行算术运算,但是在矩阵运算中是不可以的。

三、数组自身的运算

(1)min:默认找出数组的所有元素中值最小的元素,可以通过设置axis的值来按行或者列查找元素中的最小值。

(2)max:默认找出数组的所有元素中值最大的元素,可以通过设置axis的值来按行或者列查找元素中的最大值。

(3)sum:默认对数组中的所有元素进行求和运算,并返回运算结果,同样可以通过设置axis的值来按行或者列对元素进行求和运算。

(4)exp:对数组中的所有元素进行指数运算。

(5)sqrt:对数组中的所有元素进行平方根运算。

(6)square:对数组中的所有元素进行平方运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
a =np.array([[1,2,3],
[3,2,1]])

print("min of array:", a.min())
print("min of array:", a.min(axis=0))
print("min of array:", a.min(axis=1))

print("max of array:", a.max())
print("max of array:", a.max(axis=0))
print("max of array:", a.max(axis=1))

print("sum of array:", a.sum())
print("sum of array:", a.sum(axis=0))
print("sum of array:", a.sum(axis=1))

在运行后,输出的内容如下

1
2
3
4
5
6
7
8
9
min of array: 1
min of array: [1 2 1]
min of array: [1 1]
max of array: 3
max of array: [3 2 3]
max of array: [3 3]
sum of array: 12
sum of array: [4 4 4]
sum of array: [6 6]

在复杂的多维数组中,我们通过对axis参数进行不同的设置,来得到不同的运算结果:当axis为0时,计算方向是针对数组的列的;当axis为1时,计算方向是针对数组的行的。

四、随机数组

在NumPy中有许多方法可以生成不同属性的随机数,以满足在计算中使用随机数字的需求。

(1)seed:随机因子,在随机数生成器的随机因子被确定后,无论我们运行多少次随机程序,最后生成的数字都是一样的,随机因子更像把随机的过程变成一种伪随机的机制,不过这有利于结果的复现。

(2)rand:生成一个在[0,1)范围内满足均匀分布的随机样本数。

(3)randn:生成一个满足平均值为0且方差为1的正态分布随机样本数。

(4)randint:在给定的范围内生成类型为整数的随机样本数。

(5)binomial:生成一个维度指定且满足二项分布的随机样本数。

(6)beta:生成一个指定维度且满足beta分布的随机样本数。

(7)normal:生成一个指定维度且满足高斯正太分布的随机样本数。

1
2
3
4
5
6
7
8
9
import numpy as np
np.random.seed(42)

print(np.random.rand(2,3))
print(np.random.randn(2,3))
print(np.random.randint(1,10))
print(np.random.binomial(6,1))
print(np.random.beta(2,3))
print(np.random.normal(2,3))

在运行后,输出的内容如下

1
2
3
4
5
6
7
8
[[ 0.37454012  0.95071431  0.73199394]
[ 0.59865848 0.15601864 0.15599452]]
[[ 1.57921282 0.76743473-0.46947439]
[ 0.54256004-0.46341769-0.46572975]]
6
6
0.45543839870822056
2.666236704694229

我们在以上代码中确定了随机因子,所以不论运行几次,最后得到的随机结果都是一样的。

五、索引、切片和迭代

在数组中也有索引、切片和迭代,其操作过程和列表类似,不过多维数组相较于一维数组,在索引、切片和迭代等操作上会更复杂。来看一个一维数组的实例。

1
2
3
4
5
6
7
8
import numpy as np
a =np.arange(10)

print(a) #输出整个数组
print(a[:5]) #输出数组的前五个元素

for i in a: #迭代输出数组的全部元素
print(i)

在运行后,输出的内容如下

1
2
3
4
5
6
7
8
9
10
11
12
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4]
0
1
2
3
4
5
6
7
8
9

对于多维数组而言,在每个维度上都可以通过索引值进行切片,这些索引值构成的是一个用逗号分隔的元组。

1
2
3
4
5
6
7
8
9
10
11
import numpy as np

a =np.array([[1,2,3],
[4,5,6],
[7,8,9]])

print(a) #输出整个数组
print("-"*10)
print(a[1]) #输出指定维度的数据
print("-"*10)
print(a[0:2, 1:3]) #输出指定维度的数据

在运行后,输出的内容如下:

1
2
3
4
5
6
7
8
[[1 2 3]
[4 5 6]
[7 8 9]]
----------
[4 5 6]
----------
[[2 3]
[5 6]]

从以上实例的输出结果中可以看到,多维数组的切片可以分别针对多个维度进行操作,而且多维数组可以针对不同的维度进行迭代,具体的实例如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

a =np.array([[1,2,3],
[4,5,6],
[7,8,9]])

for i in a:
print(i)

print("-"*10)
for i in a:
for j in i:
print(j)

在运行后,输出的内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
[1 2 3]
[4 5 6]
[7 8 9]
----------
1
2
3
4
5
6
7
8
9

将代码中的第2种迭代方法写成如下形式,也可以达到同样的效果,这相当于将多维数组进行了扁平化处理,将其转变成了一维数组

1
2
for i in a.flat:
print(i)

Write by sheen

打赏
  • 版权声明: 版权所有属于未央。商业转载,请联系作者(邮箱:sheensong@163.com)以获取授权。 非商业转载,请注明出处并附上原文链接,谢谢配合。

请我喝杯咖啡吧~

支付宝
微信