NumPy Ndarray 对象
ndarray 内部由以下内容组成:
-
一个指向数据(内存或内存映射文件中的一块数据)的指针。
-
数据类型或 dtype,描述在数组中的固定大小值的格子。
-
一个表示数组形状(shape)的元组,表示各维度大小的元组。
-
一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
import numpy as np
a = np.array([[1, 2], [3, 4]], dtype = complex)
NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
ndarray.ndim | 秩,即轴的数量或维度的数量:a = np.arange(24) print (a.ndim) |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
调整数组:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
a.shape = (2,3) # a(2,3)
b = a.reshape(3,2) # b(3,2)
NumPy 创建数组
numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:
numpy.empty(shape, dtype = float, order = 'C')
numpy.zeros 创建指定大小的数组,数组元素以 0 来填充:
numpy.zeros(shape, dtype = float, order = 'C') # 默认为浮点数
numpy.ones创建指定形状的数组,数组元素以 1 来填充:
numpy.ones(shape, dtype = None, order = 'C')
numpy.frombuffer 用于实现动态数组。
numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
注意:buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
import numpy as np
s = b'Hello World'
a = np.frombuffer(s, dtype = 'S1')
print (a)
# 输出结果为:[b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
import numpy as np
list=range(5) # 使用 range 函数创建列表对象
it=iter(list) # 使用迭代器创建 ndarray
x=np.fromiter(it, dtype=float)
print(x) # 输出结果为:[0. 1. 2. 3. 4.]
numpy.arange:numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:
numpy.arange(start, stop, step, dtype)
import numpy as np
print (np.arange(10,20,2,dtype = float))
[10. 12. 14. 16. 18.]
numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下:
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
#将 endpoint 设为 false,不包含终止值
import numpy as np
a = np.linspace(1,10,10)
print(a) # [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
numpy.logspace 函数用于创建一个于等比数列。格式如下:
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
# base 参数意思是取对数的时候 log 的下标。
import numpy as np
a = np.logspace(0,9,10,base=2)
print (a) # [ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
NumPy 切片和索引
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。可以通过冒号分隔切片参数 start:stop:step 来进行切片操作
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
s = slice(2,8,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s]) #[2 4 6]
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b) #[2 4 6]
切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1]) # 第2列元素
print (a[1,...]) # 第2行元素
print (a[...,1:]) # 第2列及剩下的所有元素
输出结果为:
[2 4 5]
[3 4 5]
[[2 3]
[4 5]
[5 6]]
整数数组索引
#获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print (x[x > 5])
输出结果为:
[ 6 7 8 9 10 11]
使用了 ~(取补运算符)来过滤 NaN:print (a[~np.isnan(a)])
NumPy 广播(Broadcast)
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
输出结果为:
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
广播条件:数组拥有相同形状。当前维度的值相等。当前维度的值有一个是 1。若条件不满足,抛出 "ValueError: frames are not aligned" 异常。
NumPy 迭代数组
NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
a = np.arange(6).reshape(2,3)
for x in np.nditer(a):
print (x, end=", " )
控制遍历顺序
for x in np.nditer(a, order='F'):
Fortran order,即是列序优先;
修改数组形状
reshape | 不改变数据的条件下修改形状 |
flat | 数组元素迭代器 |
flatten | 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 |
ravel | 返回展开数组 |
import numpy as np
a = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:
print (row)
#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:
print (element)
原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8
numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:
ndarray.flatten(order='C') #order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组。
numpy.ravel(a, order='C')
翻转数组
transpose | 对换数组的维度 |
ndarray.T | 和 self.transpose() 相同 |
rollaxis | 向后滚动指定的轴 |
swapaxes | 对换数组的两个轴 |
numpy.transpose 函数用于对换数组的维度,格式如下:
numpy.transpose(arr, axes)
arr
:要操作的数组axes
:整数列表,对应维度,通常所有维度都会对换。
numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
arr
:数组axis
:要向后滚动的轴,其它轴的相对位置不会改变start
:默认为零,表示完整的滚动。会滚动到特定位置。
numpy.swapaxes 函数用于交换数组的两个轴,格式如下:
numpy.swapaxes(arr, axis1, axis2)
arr
:输入的数组axis1
:对应第一个轴的整数axis2
:对应第二个轴的整数
修改数组维度
broadcast | 产生模仿广播的对象 |
broadcast_to | 将数组广播到新形状 |
expand_dims | 扩展数组的形状 |
squeeze | 从数组的形状中删除一维条目 |