python数据分析之第三方模块NumPy

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

数据分析三剑客:NumpyPandasMatplotlibNumpyPadas是数据结构、Matplotlib绘图使用 。

后续代码示例都默认引入了NumPy

1
import numpy as np

创建数组

array

1
np.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

参数说明:

名称描述
object数组或嵌套的数列
dtype数组元素的数据类型,可选
copy对象是否需要复制,可选
order创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok默认返回一个与基类类型一致的数组
ndmin指定生成数组的最小维度

示例

一维数组

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

# 结果
[2 4 5 6 7 4 3]

设定维度

1
2
3
4
5
arr = np.array([2, 4, 5, 6, 7, 4, 3], ndmin=3)
print(arr)

# 结果
[[[2 4 5 6 7 4 3]]]

多维数组

1
2
3
4
5
arr = np.array([[2, 4, 5, 6, 7, 4, 3], [5, 6, 23, 9]])
print(arr)

# 结果
[list([2, 4, 5, 6, 7, 4, 3]) list([5, 6, 23, 9])]

empty

empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组

1
np.empty(shape, dtype = float, order = 'C')

参数说明:

参数描述
shape数组形状
dtype数据类型,可选
order有”C”和”F”两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。

示例

1
2
3
4
5
6
7
arr = np.empty([3, 2])
print(arr)

# 结果
[[6.23042070e-307 1.69118108e-306]
[6.23054972e-307 1.06811422e-306]
[1.33510679e-306 2.22522597e-306]]

zeros

创建指定大小的数组,数组元素以 0 来填充,且默认为浮点型

语法

1
np.zeros(shape, dtype = float, order = 'C')

参数说明

参数描述
shape数组形状
dtype数据类型,可选
order‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

示例

二维数组
1
2
3
4
5
6
arr = np.zeros([3,4])

#结果:
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
设置类型
1
2
3
4
arr = np.zeros([3,], dtype=np.int)

#结果:
[0 0 0]

ones

创建指定形状的数组,数组元素以 1 来填充,默认为浮点型

语法

1
np.ones(shape, dtype = None, order = 'C')

参数说明

参数描述
shape数组形状
dtype数据类型,可选
order‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

示例

二维数组
1
2
3
4
5
6
arr = np.ones([3,4])

#结果:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
设置类型
1
2
3
4
arr = np.ones([3,], dtype=np.int)

#结果:
[1 1 1]

random

随机数生成

seed

seed( ) 用于指定随机数生成时所用算法开始的整数值。

1.如果使用相同的seed( )值,则每次生成的随即数都相同;

2.如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。

示例

1
2
3
4
5
6
7
8
# 利用随机数种子,使得每次生成的随机数相同
np.random.seed(1)
arr = np.random.rand(3, 2)

# 结果每次随机的矩阵及元素都相同
[[0.47130726 0.74036282]
[0.80323113 0.93100884]
[0.39053087 0.34556671]]

rand

生成指定维度的的**[0,1)范围**之间的随机数,输入参数为维度

语法
1
np.random.rand(d1, d2, ……dn)
示例
1
2
3
4
5
6
arr = np.random.rand(3, 2)

# 结果
[[0.47130726 0.74036282]
[0.80323113 0.93100884]
[0.39053087 0.34556671]]

random

生成指定维度的的**[0,1)范围**之间的随机数,输入参数为维度

语法
1
np.random.random(size=None)
参数
参数描述
size数组形状,int或int元组,可选
示例
1
2
3
4
arr = np.random.random()

# 结果
0.21946016191071327
1
2
3
4
5
6
arr = np.random.random(size=(3, 2))

# 结果
[[0.93875635 0.8774334 ]
[0.35932992 0.50240798]
[0.01817927 0.84576939]]

randint

返回随机数或者随机数组成的array

语法
1
np.random.randint(low, high = None, size = None,dtype = 'l')
参数
参数描述
lowhigh数字范围区间,high必须大于low
size数组形状,int或int元组,可选
dtype数据类型,可选,默认int
示例
1
2
3
4
5
6
7
8
# 随机生成一个2行3列且元素为5到10的数组矩阵
arr = np.random.randint(low=5, high=10, size=(2, 3))
# 简写方式
arr = np.random.randint(5, 10, size=(2, 3))

# 结果
[[6 7 5]
[9 7 8]]

数组属性

NumPy 数组的维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。

NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 ·中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。

很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

NumPy 的数组中比较重要 ndarray 对象属性有

属性说明
ndarray.ndim秩,即轴的数量或维度的数量
ndarray.shape数组的维度,对于矩阵,n 行 m 列
ndarray.size数组元素的总个数,相当于 .shape 中 n*m 的值
ndarray.dtypendarray 对象的元素类型
ndarray.itemsizendarray 对象中每个元素的大小,以字节为单位
ndarray.flagsndarray 对象的内存信息
ndarray.realndarray元素的实部
ndarray.imagndarray 元素的虚部
ndarray.data包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

ndarray.ndim

ndarray.ndim 用于返回数组的维数,等于秩。

实例

1
2
3
4
5
6
7
import numpy as np 

a = np.arange(24)
print (a.ndim) # a 现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3) # b 现在拥有三个维度
print (b.ndim)

输出结果为:

1
2
1
3

ndarray.shape

ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。比如,一个二维数组,其维度表示”行数”和”列数”。

ndarray.shape 也可以用于调整数组大小。

实例

1
2
3
4
import numpy as np  

a = np.array([[1,2,3],[4,5,6]])
print (a.shape)

输出结果为:

1
(2, 3)

调整数组大小。

实例

1
2
3
4
5
import numpy as np 

a = np.array([[1,2,3],[4,5,6]])
a.shape = (3,2)
print (a)

输出结果为:

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

NumPy 也提供了 reshape 函数来调整数组大小。

实例

1
2
3
4
5
import numpy as np 

a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)

输出结果为:

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

ndarray.itemsize

ndarray.itemsize 以字节的形式返回数组中每一个元素的大小。

例如,一个元素类型为 float64 的数组 itemsiz 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节),又如,一个元素类型为 complex32 的数组 item 属性为 4(32/8)。

实例

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

# 数组的 dtype 为 int8(一个字节)
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize)

# 数组的 dtype 现在为 float64(八个字节)
y = np.array([1,2,3,4,5], dtype = np.float64)
print (y.itemsize)

输出结果为:

1
2
1
8

ndarray.flags

ndarray.flags 返回 ndarray 对象的内存信息,包含以下属性:

属性描述
C_CONTIGUOUS (C)数据是在一个单一的C风格的连续段中
F_CONTIGUOUS (F)数据是在一个单一的Fortran风格的连续段中
OWNDATA (O)数组拥有它所使用的内存或从另一个对象中借用它
WRITEABLE (W)数据区域可以被写入,将该值设置为 False,则数据为只读
ALIGNED (A)数据和所有元素都适当地对齐到硬件上
UPDATEIFCOPY (U)这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新

实例

1
2
3
4
import numpy as np 

x = np.array([1,2,3,4,5])
print (x.flags)

输出结果为:

1
2
3
4
5
6
7
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False

切片

ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。

ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

示例

一维数组

1
2
3
4
5
6
a = np.arange(10)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])

# 结果
[2 4 6]

我们也可以通过冒号分隔切片参数 start:stop:step 来进行切片操作:

1
2
3
4
5
6
a = np.arange(10)  
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b)

# 结果
[2 4 6]

冒号 : 的解释:如果只放置一个参数,如 **[2]**,将返回与该索引相对应的单个元素。如果为 **[2:]**,表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。

多维数组

多维数组同样适用上述索引提取方法

1
2
3
4
5
6
7
8
9
10
11
12
13
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 从某个索引处开始切割
print('从数组索引 a[1:] 处开始切割')
print(a[1:])

# 结果
[[1 2 3]
[3 4 5]
[4 5 6]]
从数组索引 a[1:] 处开始切割
[[3 4 5]
[4 5 6]]

切片还可以包括省略号 ,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
print('第2列元素')
print (a[...,1]) # 第2列元素
print('第2行元素')
print (a[1,...]) # 第2行元素
print('第2列及剩下的所有元素')
print (a[...,1:]) # 第2列及剩下的所有元素

# 结果
2列元素
[2 4 5]
2行元素
[3 4 5]
2列及剩下的所有元素
[[2 3]
[4 5]
[5 6]]

排序

NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法,每个排序算法的特征在于执行速度,最坏情况性能,所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。

种类速度最坏情况工作空间稳定性
'quicksort'(快速排序)1O(n^2)0
'mergesort'(归并排序)2O(n*log(n))~n/2
'heapsort'(堆排序)3O(n*log(n))0

numpy.sort()

numpy.sort() 函数返回输入数组的排序副本。函数格式如下:

1
numpy.sort(a, axis, kind, order)

参数说明:

  • a: 要排序的数组
  • axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序
  • kind: 默认为’quicksort’(快速排序)
  • order: 如果数组包含字段,则是要排序的字段
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
import numpy as np  

a = np.array([[3,7],[9,1]])
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 sort() 函数:')
print (np.sort(a))
print ('\n')
print ('按列排序:')
print (np.sort(a, axis = 0))
print ('\n')
# 在 sort 函数中排序字段
dt = np.dtype([('name', 'S10'),('age', int)])
a = np.array([("raju",21),("anil",25),("ravi", 17), ("amar",27)], dtype = dt)
print ('我们的数组是:')
print (a)
print ('\n')
print ('按 name 排序:')
print (np.sort(a, order = 'name'))

#结果
我们的数组是:
[[3 7]
[9 1]]


调用 sort() 函数:
[[3 7]
[1 9]]


按列排序:
[[3 1]
[9 7]]


我们的数组是:
[(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]


按 name 排序:
[(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]