【Python】NumPy库基本使用

来源:互联网 发布:知乎怎么发表问题 编辑:程序博客网 时间:2024/06/05 05:13

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

ndarray:NumPy库的心脏


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]])

数据类型

数据类型 描述 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位浮点(实部和虚部)组成的复数

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]])

自带的数组创建方法

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))>>> aarray([[ 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]])

基本操作


算术运算符

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

>>> a=np.arange(4)>>> aarray([0, 1, 2, 3])>>> a+4array([4, 5, 6, 7])>>> a-4array([-4, -3, -2, -1])>>> a*4array([ 0,  4,  8, 12])>>> a/2array([0, 0, 1, 1])

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

>>> b=np.arange(4,8)>>> barray([4, 5, 6, 7])>>> a+barray([ 4,  6,  8, 10])>>> a-barray([-4, -4, -4, -4])>>> a*barray([ 0,  5, 12, 21])>>> a/barray([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))>>> Aarray([[0, 1, 2],       [3, 4, 5],       [6, 7, 8]])>>> B=np.ones((3,3))>>> Barray([[ 1.,  1.,  1.],       [ 1.,  1.,  1.],       [ 1.,  1.,  1.]])>>> A*Barray([[ 0.,  1.,  2.],       [ 3.,  4.,  5.],       [ 6.,  7.,  8.]])

矩阵积

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.]])

自增和自减运算符

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

>>> a=np.arange(4)>>> aarray([0, 1, 2, 3])>>> a+=1>>> aarray([1, 2, 3, 4])>>> a-=1>>> aarray([0, 1, 2, 3])a*=2>>> aarray([0, 2, 4, 6])

通用函数

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

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

>>> a=np.arange(1,5)>>> aarray([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 ])

聚合函数

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

>>> a=np.array([3.3,4.5,1.2,5.7,0.3])>>> aarray([ 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

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


索引机制

一维数组

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

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

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

>>> a[-1]15>>> a[-5]11

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

>>> a[[1,3,5]]array([11, 13, 15])

二维数组

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

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

切片操作

一维数组

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

语法格式

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

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

>>> a=np.arange(10,16)>>> aarray([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])

二维数组

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

语法格式

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

例如

>>> A=np.arange(10,19).reshape((3,3))>>> Aarray([[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]])

数组迭代

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

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

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

>>> for item in A.flat:...     print item... 101112131415161718

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]])

条件和布尔数组


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

>>> A=np.random.random((4,4))>>> Aarray([[ 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.5array([[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])

形状变换


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

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

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

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

或者直接改变数组shape的值

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

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

>>> a.shape=(3,4)>>> aarray([[ 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]])

数组操作


连接数组

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]])

数组切分

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

>>> A=np.arange(16).reshape((4,4))>>> Aarray([[ 0,  1,  2,  3],       [ 4,  5,  6,  7],       [ 8,  9, 10, 11],       [12, 13, 14, 15]])# 水平切分>>> [B,C]=np.hsplit(A,2)>>> Barray([[ 0,  1],       [ 4,  5],       [ 8,  9],       [12, 13]])>>> Carray([[ 2,  3],       [ 6,  7],       [10, 11],       [14, 15]])# 垂直切分>>> [B,C]=np.vsplit(A,2)>>> Barray([[0, 1, 2, 3],       [4, 5, 6, 7]])>>> Carray([[ 8,  9, 10, 11],       [12, 13, 14, 15]])

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

>>> [A1,A2,A3]=np.split(A,[1,3],axis=1)>>> A1array([[ 0],       [ 4],       [ 8],       [12]])>>> A2array([[ 1,  2],       [ 5,  6],       [ 9, 10],       [13, 14]])>>> A3array([[ 3],       [ 7],       [11],       [15]])
原创粉丝点击