ndarray英文全称:n-dimensional array object,它是存储单一数据类型的多维数组
一、创建
通过给array()函数传递Python的序列对象来创建数组,如果传递的是多层嵌套的序列,将创建多维数组
a = np.array([1, 2, 3, 4])
b = np.array((5, 6, 7, 8))
c = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]])
print(a)
print('')
print(b)
print('')
print(c)
可以通过shape属性获得数组的形状
print(a.shape)
print('')
print(b.shape)
print('')
print(c.shape)
print('')
还可以通过修改数组的shape,在保持数组元素个数不变的情况下,改变数组每个轴的长度。
切记只是改变长度,不是转置
c.shape = 4,3
print(c)
当设置某个轴的元素个数为-1时,会自动计算此轴的长度
c.shape = 2,-1
print(c)
c中有12个元素,因此当shape设为2,-1
时,c的shape改成了(2,6)
使用reshape
,可以创建指定形状的新数组,原数组的形状保持不变
d = a.reshape(2,2)
print(d)
print('')
print(a)
二、元素类型
数组的元素类型可以通过dtype属性获得。也可在创建数组是通过dtype参数指定元素类型。
需要注意的是:
float类型是64位的双精度浮点类型,complex类型是128位的双精度复数类型
ai32 = np.array([1, 2, 3, 4], dtype=np.int32)
af = np.array([1, 2, 3, 4], dtype=float)
ac = np.array([1, 2, 3, 4], dtype=complex)
print(ai32.dtype)
print('')
print(af.dtype)
print('')
print(ac.dtype)
可以通过以下语句查看完整的类型
set(np.typeDict.values()) # 通过set进行去重
可以使用astype()
对数组的元素类型进行转换
t1 = np.array([1, 2, 3, 4], dtype=np.float)
t2 = np.array([1, 2, 3, 4], dtype=np.complex)
t3 = t1.astype(np.int32)
t4 = t2.astype(np.complex64)
print(t3.dtype)
print('')
print(t4.dtype)
可以看出,t1、t2的类型分别转换成了int32
和complex64
三、自动生成数组
Numpy提供了很多专门用于创建函数数组的函数
arange()
类似于range()
np.arange(0, 1, 0.1)
linspace()
通过制定开始值、终值和元素个数来创建表示等差数列的一维数组
np.linspace(0, 1, 10) # 步长为1/9
还可以通过endpoint
来控制是否包含终值,默认为True
np.linspace(0, 1, 10, endpoint=False) # 步长为1/10
logspace()
和linspace()
类似,不过创建的是等比数列
np.logspace(0, 2, 5)
即
1
0
0
10^0
100、
1
0
0.5
10^{0.5}
100.5、
1
0
1
10^1
101、
1
0
1.5
10^{1.5}
101.5、
1
0
2
10^2
102
也可以设置endpoint
,默认为True
np.logspace(0, 2, 5, endpoint = False)
基数通过base
参数指定,默认值为10
若想创建一个比例为 2 1 / 12 2^{1/12} 21/12的等比数列
np.logspace(0, 1, 12, base=2, endpoint=False)
zeros
、ones
、empty
可以创建指定形状和类型的数组
- empty
empty()
只分配数组所使用的的内存,不对数组元素进行初始化操作
np.empty((2,3), np.int)
- ones & zeros
zeros()
将数组元素初始化为0,ones()
将数组元素初始化为1
np.zeros(4, np.int)
np.ones(4, np.int)
- full
full()
将数组元素初始化为指定的值
np.full(4, np.pi)
此外,zeros_like()
、ones_like
、empty_like()
、full_like()
等函数创建和参数数组的形状和类型相同的数组。
因此,zeros_like(a)
和zeros(a.shape, a.dtype)
是等价的。
除了这些还可以通过fromfunction(fun,np)
以函数的形式对数组进行运算
def func2(i, j):
return (i + 1) * (j + 1)
np.fromfunction(func2, (9,9))
可以看出,返回的是一个九九乘法表
四、存取元素
可以使用和列表相同的方式对数组的元素进行存取
a = np.arange(10)
print(a)
print('')
print(a[5]) # 用整数作为下表获取数组中的某个元素
print('')
print(a[3:5]) # 用切片作为下表获取数组的一部分
print('')
print(a[:5]) # 切片中省略开始的下标
print('')
print(a[:-1]) # 下标为负数表示从最后往前数
下标还可以用来修改元素的值
a[2:4] = 100, 101
print(a)
当使用整数列表对数组元素进行存取时,将使用列表中的每个元素作为下标。使用列表作为下标得到的数组不和原始数组共享数据
x = np.arange(10, 1, -1)
print(x)
print('')
a = x[[3, 3, 1, 8]] # 获取x中下标为3、3、1、8的数并组成一个新的数组
b = x[[3, 3, -3, 8]] # 下标同样也可以是hi负数
print(a)
print('')
print(b)
修改b[2]
的值,但是由于和x不共享内存,x的值不变
b[2] = 100
print(b)
print('')
print(x)
当使用布尔数组b作为下标存取x中的元素时,将获得x中与b中True对应的元素。
注意只对应布尔数组,不能对应布尔列表
x = np.arange(5,0,-1)
print(x)
print('')
print(x[np.array([True, False, True, False, False])]) # 返回第0个和第2个
五、多维数组
多维数组以嵌套列表的形式创建
x = np.array([[0,1,2,3,4], [6,7,8,9,10]])
print(x)
在一定情况下还可以通过以下方式创建
a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
print(a)
其本质其实就是有纵向量(0, 10, 20, 30, 40, 50)
和横向量(0, 1, 2, 3, 4, 5)
相加而得。
多维数组以元组作为下标存取
x = np.array([[0,1,2,3,4], [6,7,8,9,10]])
print(x)
print('')
print(x[0,2]) # x[0,2]等价于x[(0,2)]
为什么使用元组作为下标?
Python的下标语法(用[])本身并不支持多维,但是可以使用任何对象作为下标,因此NumPy使用元组作为下标存取数组中的元素,使用元组可以很方便地表示多个轴的下标。
在多维数组的下标中,也可以使用整数元组或列表、整数数组和布尔数组
# 整数数组
a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
print(a)
print('')
print(a[(0,1,2,3),(1,2,3,4)])
a[(0,1,2,3),(1,2,3,4)]
实际上也是一个由元组存取,
等价于a[0,1]
、a[1,2]
、a[2,3]
、a[3,4]
# 整数数组
a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
print(a)
print('')
print(a[3:, [0,2,5]]) # 第3:行,第0、2、5列
# 布尔数组
a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
print(a)
print('')
mask = np.array([1,0,1,0,0,1], dtype=np.bool)
print(a[mask, 2]) # 第0、2、5行,第2列