1.Numpy数组对象
Numpy中的ndarray是一个多为数组对象,该对象由两部分组成:
- 实际的数据;
- 描述这些数据的元数据
大部分的数组操作仅仅修改元数据部分,而不修改底层的实际数据。
Numpy数组一般是同质的,即数组中的所有元素类型必须是一致的。这样有一个好处:如果我们知道数组中的元素均为同一类型,该数组所用的存储空间就很容易确定下来。与Python中一样,Numpy数组的下表也是从0开始的。
使用arange函数可以创建数组
import numpy as np
a = np.array(5)
# print a:array([0,1,2,3,4])
# type(a):<class 'numpy.ndarray'>
# a.dtype :dtype('int32')/dtype('int64')
# a.shape:(5,)
type(a)获取的是数组a的类型;a.type获取的是数组a中元素的类型,这个结果与安装的Python有关;a.shape返回的是一个元组,元组的元素即为数组每一个维度上的大小。
2.多维数组
创建一个多维数组并显示该数组的维度
m = np.array([arange(2),arange(2)])
# m: array([[0,1],
[0,1]])
m.shape
#(2,2)
m1 = np.array([m,m])
#m1是一个三维数据
通过调用help函数可以查看np.array方法的详细信息
np.array函数的参数列表为:
- object: array_like
- dtype: 指定数组中元素的类型(可选)
- copy: bool类型。默认为True(可选)
- order: {‘K’,’A’,’C’,’F’},默认为为‘K’(可选)
- subok: bool类型,默认为False(可选)
- ndim: int类型,制定数组的最小维数(可选)
np.array([1,2,3],ndim=2)
#array([[1,2,3]])
np.array([1,2,3],dtype=complex)
#array([1.+0.j,2.+0.j,3.+0.j])
2.1 选取数组元素
首先创建一个2x2的多维数组:
a = np.array([[1,2],[3,4]])
# array([[1,2],
[3,4]])
利用下表选取数组中的元素(与matlab类似)
a[0,0]
# 1
a[0,1]
# 2
#...
2.2 Numpy数据类型
Python支持的数据类型有整型、浮点型以及复数型,如下表所示(从教材中copy得来的):
每一种数据类型均有对应的类型转换函数
float64(42)
# 42.0
int8(42.0)
#42
bool(42)
#True
complex(1)
#1+0j
要注意复数不能转换为整数和浮点数
2.3 数据类型对象
数据类型对象是numpy.dtype类的实例。Numpys数组是有数据类型的,更确切地说,Numpy数组中的每一个元素均为相同的数据类型。数据类型对象可以给出单个数组元素在内存中占用的字节数,即dtype类的itemsize属性:
a.dtpye.itemsize
# 8
3. 一维数组的索引和切片
一维数组的切片操作与Python列表的切片操作很相似。
a = np.arange(9)
#array([0,1,2,3,4,5,6,7,8])
a[3:7]
#array([3,4,5,6])
a[:7:2]
#array([0,2,4,6])
a[::-1]
#array([8,7,6,5,4,3,2,1,0])
4.多维数组的切片和索引
多维数组的切片和索引与matlab中相关操作比较相似
#利用reshape函数创建一个多维数组
b = np.arange(24).reshape(2,3,4)
b.shape
#(2,3,4)
b
#array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
b[0,0,0]
#0
b[:,0,0]
#array([0,12])
b[0]#b[0,:,:]/b(0,...)
#array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11]])
b[0,1]
#array([4,5,6,7])
b[0,1,::2]
#array([4,6])
5.改变多维数组的维度
(1)ravel :对多维数组进行展平操作,返回一个展平后的一维数组,原始数组不变
b = np.arange(24).reshape(2,3,4)
b
#array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
c = b.ravel()
c
#array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
b
#array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
(2)flatten: 功能与ravel函数相同(不过,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图?)
d = b.flatten()
d
#array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23])
b
#array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
(3)用元组设置维度。除了可以用reshape函数,也可以直接使用一个正整数元组来设置数组的维度
b.shape(6,4)
b
#array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9,10,11],
[12,13,14,15],
[16,17,18,19],
[20,21,22,23]])
(4)transpose:实现转置
一维数组的转置还是它本身
b.transpose()
#array([[ 0, 4, 8, 12, 16, 20],
[ 1, 5, 9, 13, 17, 21],
[ 2, 6,10, 14, 18, 22],
[ 3, 7,11, 15, 19, 23]])
(5)resize :与reshape的功能一样,不过reshape函数不会改变原始数组,resize则会改变
b.resize((2,12))
b
#array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
[12,13,14,15,16,17,18,19,20,21, 22, 23]])
6.数组的组合
Numpy数组有水平组合、垂直组合、深度组合等多种组合方式
(1)水平组合:hstack函数,concatenate函数
a = np.arange(9).reshape(3,3)
a
#array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
b = 2*a
b
#array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14,16]])
np.hstack((a,b))
#array([[ 0, 1, 2, 0, 2, 4],
[ 3, 4, 5, 6, 8,10],
[ 6, 7, 8,12,14,16]])
#或者使用concatenate函数来实现
np.concatenate((a,b),axis=1)
水平组合示意图
(2)垂直组合:vstack函数/concatenate函数
np.vstack((a,b))
#array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 0, 2, 4],
[ 6, 8,10],
[12,14,16]])
#也可以使用concatenate函数
np.concatenate((a,b),axis=0)
(3)深度组合:dstack函数
np.dstack((a,b))
#array([[[0, 0],
[1, 2],
[2, 4]],
[[3, 6],
[4, 8],
[5,10]],
[[6,12],
[7,14],
[8,16]]])
(4)列组合:column_stack
对于二位数组而言,列组合等价于水平组合
(5)行组合:row_stack
对于二位数组而言,行组合等价于垂直组合
7.数组的分割
(1)水平分割:hsplit/split
a = np.arange(9).reshape(3,3)
np.hsplit(a,3)
#[array([[0],
[3],
[6]]),
array([[1],
[4],
[7]]),
array([[2],
[5],
[8]])]
#也可以使用split函数
np.split(a,3,axis=1)
(2)垂直分割:vsplit/split
np.vsplit(a,3)
#[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
#也可以使用split函数
np.split(a,3,axis=0)
(3)深度分割:dsplit
c = np.arange(27).reshape(3, 3, 3)
c
#array([[[ 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]]])
dsplit(c, 3)
#[array([[[ 0],
[ 3],
[ 6]],
[[ 9],
[12],
[15]],
[[18],
[21],
[24]]]),
array([[[ 1],
[ 4],
[ 7]],
[[10],
[13],
[16]],
[[19],
[22],
[25]]]),
array([[[ 2],
[ 5],
[ 8]],
[[11],
[14],
[17]],
[[20],
[23],
[26]]])]
8.数组的属性
除了shape,dtype属性以外,数组还有其他属性:
(1)ndim属性,给出数组的维数,或者数组轴的数目
(2)size属性,给出数组中元素的总数目
(3)itemsize属性,给出数组中元素在内存中所占的字节数
(4)nbytes属性,给出整个数组在内存中所占的字节数
(5)T属性,给出数组的转置数组
9.数组的转换
(1)使用tolist函数可以将数组转换为列表
b = np.array([1+1j,3+2j])
b.tolist()
#[(1+1j),(3+2j)]
(2)astype函数可以改变数组的元素类型
b.astype('int')
#array([1,2])