提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
数组的属性
- numpy.ndarray.ndim 用于返回数组的维数(轴的个数)也称为秩,一维数组的秩为 1,二维数组的秩为 2,以此类推。
- numpy.ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。 3. numpy.ndarray.size 数组中所有元素的总量,相当于数组的 shape 中所有元素的乘积,例如矩阵的元素总量为行与列的乘积。
- numpy.ndarray.dtype ndarray 对象的元素类型。
- numpy.ndarray.itemsize 以字节的形式返回数组中每一个元素的大小
其代码展示如下:
import numpy as np
a = np.array([1,2,3,4,5])
print(a.shape)
print(a.dtype)
print(a.size)
print(a.ndim)
print(a.itemsize)
b = np.array([[1,2,3],[4,5,6.5]])
print(b.shape)
print(b.dtype)
print(b.size)
print(b.ndim)
print(b.itemsize)
##结果如下:
(5,)
int32
5
1
4
(2, 3)
float64
6
2
8
在 ndarray 中所有元素必须是同一类型,否则会自动向下转换, int->float->str 。
副本与视图
在 Numpy 中,尤其是在做数组运算或数组操作时,返回结果不是数组的 副本 就是 视图。 在 Numpy 中,所有赋值运算不会为数组和数组中的任何元素创建副本。
- numpy.ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。
其代码展示如下:
x = np.array([1,2,3,4,5,6,7,8])
y = x
y[0] = -1
print(x)
print(y)
##其结果如下:
[-1 2 3 4 5 6 7 8]
[-1 2 3 4 5 6 7 8]
可以看出两次输出的结果一样。
数组切片操作返回的对象只是原数组的视图。(此处若不明白切片的含义,可以往下看“切片索引”的相关定义与内容)
x = np.array([[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]])
y = x
y[::2,:3:2]=-1
print(x)
print(y)
##结果如下:
[[-1 12 -1 14 15]
[16 17 18 19 20]
[-1 22 -1 24 25]
[26 27 28 29 30]
[-1 32 -1 34 35]]
[[-1 12 -1 14 15]
[16 17 18 19 20]
[-1 22 -1 24 25]
[26 27 28 29 30]
[-1 32 -1 34 35]]
索引与切片
数组索引机制指的是用方括号([])加序号的形式引用单个数组元素,它的用处很多,比如抽取元素,选取数组的几个元素,甚至为其赋一个新值。
数组索引
要获取数组的单个元素,指定元素的索引即可。
x = np.array([[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]])
print(x[2])
print(x[2][1])
print(x[2,1])
##结果如下:
[21 22 23 24 25]
22
22
想要取出某一行或者某个元素,直接print然后指定元素的位置即可。
切片索引
切片操作是指抽取数组的一部分元素生成新数组。对 python 列表进行切片操作得到的数组是原数组的副本,而对 Numpy 数据进行切片操作得到的数组则是指向相同缓冲区的视图。
如果想抽取(或查看)数组的一部分,必须使用切片语法,也就是,把几个用冒号( start:stop:step )隔开的数字置于方括号内。
为了更好地理解切片语法,还应该了解不明确指明起始和结束位置的情况。如省去第一个数字,numpy 会认为第一个数字是0;如省去第二个
数字,numpy 则会认为第二个数字是数组的最大索引值;如省去最后一个数字,它将会被理解为1,也就是抽取所有元素而不再考虑间隔。
通过代码理解更清楚:
对一维数组切片:
x = np.array([1,2,3,4,5,6,7,8])
print(x[0:2])
print(x[1:5:2])
print(x[2:])
print(x[:2])
print(x[-2:])
print(x[:-2])
print(x[:])
print(x[::-1])
##结果如下:
[1 2]
[2 4]
[3 4 5 6 7 8]
[1 2]
[7 8]
[1 2 3 4 5 6]
[1 2 3 4 5 6 7 8]
[8 7 6 5 4 3 2 1]
对二维数组切片:
x = np.array([[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]])
print(x[0:2])
print(x[1:5:2])
print(x[2:])
print(x[:2])
print(x[-2:])
print(x[:-2])
print(x[:])
print(x[2,:])
print(x[:,2])
print(x[0,1:4])
print(x[1:4,0])
print(x[1:3,2:4])
print(x[::2, ::2])
print(x[::-1, :])
print(x[:, ::-1])
##结果如下:
[[11 12 13 14 15]
[16 17 18 19 20]]
[[16 17 18 19 20]
[26 27 28 29 30]]
[[21 22 23 24 25]
[26 27 28 29 30]
[31 32 33 34 35]]
[[11 12 13 14 15]
[16 17 18 19 20]]
[[26 27 28 29 30]
[31 32 33 34 35]]
[[11 12 13 14 15]
[16 17 18 19 20]
[21 22 23 24 25]]
[[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]]
[21 22 23 24 25]
[13 18 23 28 33]
[12 13 14]
[16 21 26]
[[18 19]
[23 24]]
[[11 13 15]
[21 23 25]
[31 33 35]]
[[31 32 33 34 35]
[26 27 28 29 30]
[21 22 23 24 25]
[16 17 18 19 20]
[11 12 13 14 15]]
[[15 14 13 12 11]
[20 19 18 17 16]
[25 24 23 22 21]
[30 29 28 27 26]
[35 34 33 32 31]]
以上展示了对二维数组的各种切片方式,可以仔细斟酌,真正理解二维数组切片的含义。
有关数组的索引还有整数数组索引和索尔索引,应用时再详细说明。
数组迭代
除了for循环,Numpy 还提供另外一种更为优雅的遍历方法。
x = np.array([[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]])
y = np.apply_along_axis(np.sum,0,x)
print(y)
y=np.apply_along_axis(np.sum,1,x)
print(y)
##结果如下:
[105 110 115 120 125]
[ 65 90 115 140 165]
数组操作
numpy.ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。
import numpy as np
x = np.array([4,5,7,12,56,32])
print(x.shape)
x.shape = [3,2]
print(x)
##结果如下:
[[ 4 5]
[ 7 12]
[56 32]]
numpy.ndarray.flat 将数组转换为一维的迭代器,可以用for访问数组每一个元素
x = np.array([[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]])
y = x.flat
print(y)
for i in y:
print(i,end='')
##结果如下:
11121314151617181920212223242526272829303132333435
numpy.ndarray.flatten([order=‘C’]) 将数组的副本转换为一维数组,并返回。
order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。(简记)
x = np.array([[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]])
y = x.flatten()
print(y)
##结果如下:
[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]
numpy.ravel(a, order=‘C’) Return a contiguous flattened array.,ravel() 返回的是视图。
x = np.array([[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]])
y = np.ravel(x)
print(y)
对元素进行修改,
y[3] = 0
print(x)
#结果如下:
[[11 12 13 0 15]
[16 17 18 19 20]
[21 22 23 24 25]
[26 27 28 29 30]
[31 32 33 34 35]]
输出了新的数组。
numpy.reshape(a, newshape[, order=‘C’]) 在不更改数据的情况下为数组赋予新的形状。reshape() 函数当参数 newshape = [rows,-1] 时,将根据行数自动确定列数。
x = np.arange(12)
y = np.reshape(x, [3, 4])
print(y.dtype)
print(y)
##结果如下:
int32
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
数组转置
- numpy.transpose(a, axes=None) Permute the dimensions of an array.
- numpy.ndarray.T Same as self.transpose() , except that self is returned if self.ndim < 2
x = np.random.rand(5, 5) * 10
x = np.around(x, 2)
print(x)
##结果如下:
[[0.68 8.96 7.46 9.24 4.54]
[2.45 9.88 4.73 9.66 0.02]
[5.26 5.74 2.09 7.75 7.88]
[8.72 5.01 2.05 2.15 9.26]
[4.92 8.55 9.23 8.85 3.48]]
y = x.T
print(y)
##结果如下:
[[0.68 2.45 5.26 8.72 4.92]
[8.96 9.88 5.74 5.01 8.55]
[7.46 4.73 2.09 2.05 9.23]
[9.24 9.66 7.75 2.15 8.85]
[4.54 0.02 7.88 9.26 3.48]]
可以看出,数组x的行和列的元素互换了,这就是所谓的转置。
更改维度
当创建一个数组之后,还可以给它增加一个维度,这在矩阵计算中经常会用到。
- numpy.newaxis = None None 的别名,对索引数组很有用。很多工具包在进行计算时都会先判断输入数据的维度是否满足要求,如果输入数据达不到指定的维度时,可以使用 newaxis 参数来增加一个维度。
x = np.array([1, 2, 9, 4, 5, 6, 7, 8])
print(x.shape)
print(x)
y = x[np.newaxis, :]
print(y.shape)
print(y)
##结果如下:
(8,)
[1 2 9 4 5 6 7 8]
(1, 8)
[[1 2 9 4 5 6 7 8]]
数组组合
如果要将两份数据组合到一起,就需要拼接操作
numpy.concatenate((a1, a2, …), axis=0, out=None) Join a sequence of arrays along an existing axis.
连接沿现有轴的数组序列(原来x,y都是一维的,拼接后的结果也是一维的)。
x = np.array([1, 2, 3])
y = np.array([7, 8, 9])
z = np.concatenate([x, y])
print(z)
##拼接的结果如下:
[1 2 3 7 8 9]
总结
本次主要 学习的是数组的有关操作,仅仅是对教材的内容进行了代码的运行,其本质还是存在一些疑问,需要更多的练习。