《numpy学习指南》学习笔记——数组

时间:2021-04-16 21:21:50

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得来的):
《numpy学习指南》学习笔记——数组
每一种数据类型均有对应的类型转换函数

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)

水平组合示意图
《numpy学习指南》学习笔记——数组
(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])