【Python】NumPy库基本使用

本文详细介绍了Python中的NumPy库,包括ndarray的基础操作,如array()函数、数据类型和dtype选项,以及创建数组的方法。讨论了算术运算、矩阵积、自增自减运算符、通用函数和聚合函数。还涵盖了索引、切片、迭代,条件和布尔数组,形状变换,数组连接和切分等高级操作。是Python数据分析初学者的实用指南。
摘要由CSDN通过智能技术生成

本文整理自《Python数据分析实战》

1. ndarray:NumPy库的心脏

1.1 array()函数

最常用于创建数组的方法是使用array()函数,参数为单层或嵌套列表:

# 单层列表
>>> np.array([1,2,3])
array([1, 2, 3])

# 嵌套列表
>>> np.array([[1,2,3],[4,5,6]])
array([[1, 2, 3],
       [4, 5, 6]])

参数还可以是嵌套元组或元组列表:

# 嵌套元组
>>> np.array(((1,2,3),(4,5,6)))
array([[1, 2, 3],
       [4, 5, 6]])

# 元组列表
>>> np.array([(1,2,3),(4,5,6)])
array([[1, 2, 3],
       [4, 5, 6]])

此外,参数可以是元组或列表组成的列表:

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

1.2 数据类型

数据类型描述
bool_以字节存储的布尔值(True 或 False)
int_默认的整数类型(和 C 的 long 一样,是 int64 或者 int32)
intc和 C 的 int 相同(一般为 int64 或 int32)
intp用于下标的整数(和 C 的 ssize_t 相同,一般为int64 或者 int32)
int8字节(-128 到 127)
int16整数(-32768 到 32767)
int32整数(-2147483648 到 2147483647)
int64整数(-9223372036854775808 到 9223372036854775807)
uint8无符号整数(0 到 255)
uint16无符号整数(0 到 65535)
uint32无符号整数(0 到 4294967295)
uint64无符号整数(0 到 18446744073709551615)
float_float64 的简写
float16半精度浮点:1位符号,5位指数,10位尾数
float32单精度浮点:1位符号,8位指数,23位尾数
float64双精度浮点:1位符号,11位指数,52位尾数
complex_complex128 的简写
complex64由两个32位浮点(实部和虚部)组成的复数
complex128由两个64位浮点(实部和虚部)组成的复数

1.3 dtype选项

array()函数默认根据列表或元素序列中各元素的数据类型,为ndarray()对象指定最合适的数据类型。可以用dtype选项作为函数array()的参数,明确指定dtype的类型。

比如要定义一个复数数组:

>>> np.array([[1,2,3],[4,5,6]],dtype=complex)
array([[ 1.+0.j,  2.+0.j,  3.+0.j],
       [ 4.+0.j,  5.+0.j,  6.+0.j]])

1.4 自带的数组创建方法

NumPy库有几个函数能够生成包含初始值的N维数组:

  • zeros()
  • ones()
  • arange()
  • reshape()
  • linspace()
  • random()

zeros()函数能够生成由shape参数指定维度信息、元素均为零的数组:

>>> np.zeros((3,3))
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

ones()函数与zeros()函数相似,生成元素均为1的数组:

>>> np.ones((3,3))
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

arange()函数根据参数生成包含一个数值序列的数组:

# 生成从0到9的数组
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 生成从4到9的数组
>>> np.arange(4,10)
array([4, 5, 6, 7, 8, 9])

# 按步长为2生成从0到9的数组
>>> np.arange(0,10,2)
array([0, 2, 4, 6, 8])

# 按步长为0.6生成从4到9的数组
>>> np.arange(4,10,0.6)
array([ 4. ,  4.6,  5.2,  5.8,  6.4,  7. ,  7.6,  8.2,  8.8,  9.4])

reshape()函数通常结合arange()函数使用,改变数组的型:

# 将一维数组a变为3*4的数组
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

# 将a变回为一维数组
>>> a.reshape((12,))
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

linspace()函数跟arange()函数相似,前两个参数指定序列的开头和结尾,第三个参数指定将数组拆分成几个部分:

>>> np.linspace(0,10,5)
array([  0. ,   2.5,   5. ,   7.5,  10. ])

random()函数使用随机数填充数组:

# 生成一维数组
>>> np.random.random(3)
array([ 0.0092522 ,  0.44961339,  0.85684498])

# 生成多维数组
>>> np.random.random((3,3))     
array([[ 0.50311642,  0.25961784,  0.30587642],
       [ 0.55388356,  0.92739877,  0.26140058],
       [ 0.63482092,  0.45938232,  0.84053653]])

2. 基本操作

2.1 算术运算符

算术运算符可以用于数组和标量之间:

>>> a=np.arange(4)
>>> a
array([0, 1, 2, 3])

>>> a+4
array([4, 5, 6, 7])

>>> a-4
array([-4, -3, -2, -1])

>>> a*4
array([ 0,  4,  8, 12])

>>> a/2
array([0, 0, 1, 1])

还可以用于两个数组之间,这两个数组的元素位置必须相同,也就是具有相同的型:

>>> b=np.arange(4,8)
>>> b
array([4, 5, 6, 7])

>>> a+b
array([ 4,  6,  8, 10])

>>> a-b
array([-4, -4, -4, -4])

>>> a*b
array([ 0,  5, 12, 21])

>>> a/b
array([0, 0, 0, 0])

此外,算术运算符还适用于返回值为NumPy数组的函数:

>>> a*np.sin(b)
array([-0.        , -0.95892427, -0.558831  ,  1.9709598 ])

>>> a*np.sqrt(b)
array([ 0.        ,  2.23606798,  4.89897949,  7.93725393])

对于多维数组是一样适用的:

>>> A=np.arange(9).reshape((3,3))
>>> A
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

>>> B=np.ones((3,3))
>>> B
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

>>> A*B
array([[ 0.,  1.,  2.],
       [ 3.,  4.,  5.],
       [ 6.,  7.,  8.]])

2.2 矩阵积

NumPy用dot()函数表示矩阵积:

>>> np.dot(A,B)
array([[  3.,   3.,   3.],
       [ 12.,  12.,  12.],
       [ 21.,  21.,  21.]])

另外一种写法:

>>> A.dot(B)
array([[  3.,   3.,   3.],
       [ 12.,  12.,  12.],
       [ 21.,  21.,  21.]])

矩阵积不遵循交换律:

>>> B.dot(A)
array([[  9.,  12.,  15.],
       [  9.,  12.,  15.],
       [  9.,  12.,  15.]])

2.3 自增和自减运算符

Python没有++--运算符,只有+=-=运算符。这两个运算符得到的结果直接赋给参与运算的数组自身:

>>> a=np.arange(4)
>>> a
array([0, 1, 2, 3])

>>> a+=1
>>> a
array([1, 2, 3, 4])

>>> a-=1
>>> a
array([0, 1, 2, 3])

a*=2
>>> a
array([0, 2, 4, 6])

2.4 通用函数

通用函数对数组中的各个元素逐一进行操作,生成的结果组成一个新的输出数组。

三角函数等许多数学运算符合通用函数的定义:

>>> a=np.arange(1,5)
>>> a
array([1, 2, 3, 4])

>>> np.sqrt(a)
array([ 1.        ,  1.41421356,  1.73205081,  2.        ])

>>> np.log(a)
array([ 0.        ,  0.69314718,  1.09861229,  1.38629436])

>>> np.sin(a)
array([ 0.84147098,  0.90929743,  0.14112001, -0.7568025 ])

2.5 聚合函数

聚合函数对一组值操作,返回一个单一值作为结果:

>>> a=np.array([3.3,4.5,1.2,5.7,0.3])
>>> a
array([ 3.3,  4.5,  1.2,  5.7,  0.3])

>>> a.sum()
15.0

>>> a.min()
0.29999999999999999

>>> a.max()
5.7000000000000002

>>> a.mean()
3.0

>>> a.std()
2.0079840636817816

3. 索引机制、切片和迭代方法

3.1 索引机制

3.1.1 一维数组

要获取数组的单个元素,指定元素的索引即可:

>>> a=np.arange(10,16)
>>> a

array([10, 11, 12, 13, 14, 15])
>>> a[4]
14

还可以用负数作为索引,和Python序列的负数索引一致:

>>> a[-1]
15

>>> a[-5]
11

方括号里传入多个索引值,可以同时选择多个元素:

>>> a[[1,3,5]]
array([11, 13, 15])
3.1.2 二维数组

要获取或选取矩阵中的元素,索引值为[行索引,列索引]

>>> A=np.arange(10,19).reshape((3,3))
>>> A
array([[10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])

>>> A[1,2]
15

3.2 切片操作

3.2.1 一维数组

切片操作指抽取数组的一部分元素生成新数组,该数组是指向相同缓冲区的视图。

语法格式:

a[行索引:列索引:步长]

# 行索引缺省:默认为0
# 列索引缺省:默认为该数组的索引最大值
# 步长缺省:默认为1

如想抽取或查看数组的一部分:

>>> a=np.arange(10,16)
>>> a
array([10, 11, 12, 13, 14, 15])

>>> a[1:5]
array([11, 12, 13, 14])

>>> a[1:5:2]
array([11, 13])

>>> a[::2]
array([10, 12, 14])

>>> a[:5:2]
array([10, 12, 14])

>>> a[:5:]
array([10, 11, 12, 13, 14])
3.2.2 二维数组

二维数组需要分别指定行和列的索引值。

语法格式:

A[行索引:列索引:步长 , 行索引:列索引:步长]

例如:

>>> A=np.arange(10,19).reshape((3,3))
>>> A
array([[10, 11, 12],
       [13, 14, 15],
       [16, 17, 18]])

# 抽取第一行
>>> A[0,:]
array([10, 11, 12])

# 抽取第一列
>>> A[:,0]
array([10, 13, 16])

# 抽取一个范围
>>> A[0:2,0:2]
array([[10, 11],
       [13, 14]])

# 抽取不连续的行或列,要把索引放在数组里
>>> A[[0,2],0:2]
array([[10, 11],
       [16, 17]])

3.3 数组迭代

可以使用for语句对数组迭代:

>>> a=np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> for i in a:
...     print i
... 
0
1
2
3
4
5
6
7
8
9

如果想遍历矩阵的每个元素,可以用for语句遍历A.flat

>>> for item in A.flat:
...     print item
... 
10
11
12
13
14
15
16
17
18

NumPy还提供了一个处理循环的方法apply_along_axis()函数。这个函数接收三个参数:

apply_along_axis(聚合函数或通用函数,,数组)

# 如果axis选项的值为0,按列进行迭代;值为1,则按行

例如先求每一列的平均数,再求每一行的平均数:

>>> np.apply_along_axis(np.mean,axis=0,arr=A)
array([ 13.,  14.,  15.])

>>> np.apply_along_axis(np.mean,axis=1,arr=A)
array([ 11.,  14.,  17.])

如果使用通用函数,实际上是按照指定的轴逐元素遍历数组,所以按行或列迭代结果是一样的:

>>> def foo(x):
...     return x/2
... 

>>> np.apply_along_axis(foo,axis=1,arr=A)
array([[5, 5, 6],
       [6, 7, 7],
       [8, 8, 9]])

>>> np.apply_along_axis(foo,axis=0,arr=A)
array([[5, 5, 6],
       [6, 7, 7],
       [8, 8, 9]])

4. 条件和布尔数组

如果对数组使用条件运算符,将会得到由布尔值组成的数组:

>>> A=np.random.random((4,4))
>>> A
array([[ 0.86118588,  0.35409283,  0.7896701 ,  0.57151539],
       [ 0.36440236,  0.46306654,  0.61989782,  0.94423436],
       [ 0.63706687,  0.85048501,  0.82146301,  0.13815874],
       [ 0.83226105,  0.83114022,  0.35471327,  0.64492001]])

>>> A<0.5
array([[False,  True, False, False],
       [ True,  True, False, False],
       [False, False, False,  True],
       [False, False,  True, False]], dtype=bool)

可以把条件表达式放在方括号中,将会返回一个满足条件的元素组成的新数组:

>>> A[A<0.5]
array([ 0.35409283,  0.36440236,  0.46306654,  0.13815874,  0.35471327])

5. 形状变换

除了通过reshape()函数改变数组的形状之外,还可以通过将表示新形状的元组直接赋给数组的shape属性:

>>> a=np.arange(12)
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

>>> a.shape=(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

可以使用ravel()函数将数组转为一维数组:

>>> a=a.ravel()
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

或者直接改变数组shape的值:

>>> a.shape=(12)
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

另外还能用transpose()函数实现交换行列位置的矩阵转置:

>>> a.shape=(3,4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

>>> a.transpose()
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])

6. 数组操作

6.1 连接数组

NumPy使用栈的概念来连接数组。vstack()函数执行垂直入栈,hstack()函数执行水平入栈:

>>> A=np.ones((3,3))
>>> B=np.zeros((3,3))

# 垂直连接
>>> np.vstack((A,B))
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

# 水平连接
>>> np.hstack((A,B))
array([[ 1.,  1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.,  0.]])

还有两个用于多个数组之间栈操作的函数是column_stack()函数和row_stack()函数。这两个函数一般将一维数组作为列或行压入栈,以形成一个新的二维数组:

>>> a=np.array([0,1,2])
>>> b=np.array([3,4,5])
>>> c=np.array([6,7,8])

# 以列连接
>>> np.column_stack((a,b,c))
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])

# 以行连接
>>> np.row_stack((a,b,c))
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

6.2 数组切分

连接数组的逆操作就是把一个数组分成几部分。水平切分用hsplit()函数,垂直切分用vsplit()函数:

>>> A=np.arange(16).reshape((4,4))
>>> A
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

# 水平切分
>>> [B,C]=np.hsplit(A,2)
>>> B
array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]])
>>> C
array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15]])

# 垂直切分
>>> [B,C]=np.vsplit(A,2)
>>> B
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
>>> C
array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])

split()函数可以把数组分为几个不对称的部分,需要指定被切分部分的索引。指定axis=1时,索引是列索引;指定axis=0时,是行索引:

>>> [A1,A2,A3]=np.split(A,[1,3],axis=1)

>>> A1
array([[ 0],
       [ 4],
       [ 8],
       [12]])
>>> A2
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10],
       [13, 14]])
>>> A3
array([[ 3],
       [ 7],
       [11],
       [15]])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值