首先导入 numpy 包
代码语言:javascript复制import numpy as np
通过 arange 函数创建一个一维数组 x
代码语言:javascript复制x = np.arange
print(x)
'''
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
'''
使用 reshape 方法将一维数组转换为 3x5 的二维数组 X
代码语言:javascript复制X = np.arange(15).reshape(3, 5)
print(X)
'''
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
'''
基本属性
ndim 属性查看数组的维度
代码语言:javascript复制print(x.ndim) # 1
print(X.ndim) # 2
shape 属性查看数组的维度,返回值是一个元组,元组中对应位置的值为数组中对应维度的元素个数。
代码语言:javascript复制print(x.shape) # (10,)
print(X.shape) # (3, 5)
size 属性查看数组中的元素个数
代码语言:javascript复制print(x.size) # 10
print(X.size) # 15 (3 x 5)
numpy.array 的数据访问
代码语言:javascript复制print(x)
'''
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
'''
代码语言:javascript复制print(x[0]) # 0
print(x[-1]) # 9
代码语言:javascript复制print(X)
'''
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
'''
代码语言:javascript复制# [][]同样可以访问,但是 numpy 不建议这样写
print(X[0][0]) # 0
# 推荐写法如下,与 X[(0,0)] 等价
print(X[0, 0]) # 0
一维数组的切片操作可以参考 Python 中对列表的切片操作
代码语言:javascript复制print(x)
'''
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
'''
print(x[0:5])
'''
array([0, 1, 2, 3, 4])
'''
print(x[:5])
'''
array([0, 1, 2, 3, 4])
'''
print(x[5:])
'''
array([5, 6, 7, 8, 9])
'''
print(x[::2])
'''
array([0, 2, 4, 6, 8])
'''
print(x[::-1])
'''
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
'''
numpy 支持二维数组的切片操作,甚至更高维度
代码语言:javascript复制print(X)
'''
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
'''
# 输出二维数组的前两行前三列
print(X[:2, :3])
'''
array([[0, 1, 2],
[5, 6, 7]])
'''
代码语言:javascript复制# 与X[:2, :3]不等价
print(X[:2][:3])
'''
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
'''
X[:2][:3]
与 X[:2, :3]
不等价,如果是 X[:2][:3]
,程序会先执行 X[:2]
,也就是输出 X 的前两行元素,X[:2]
返回的是一个新的二维数组 new_X
,而接下来相当于执行 new_X[:3]
,输出 new_X
的前三行。
X[:2][:3]
等价于new_X = X[:2]
和new_X[:3]
这也是为什么推荐使用 X[0, 0]
而不是 X[0][0]
的原因。
子数组与原数组
在 Python 中对列表进行切片实际上创建了新的列表,而 Numpy 优先考虑效率,所以在 numpy 中,如果修改了子数组,那么相应的原数组也会发生改变,反之亦然。(切片的子数组通过引用与原数组建立联系,而不是创建新的数组)
代码语言:javascript复制# 通过切片生成子数组
subX = X[:2, :3]
print(subX)
'''
array([[0, 1, 2],
[5, 6, 7]])
'''
# 修改子数组
subX[0, 0] = 100
print(subX)
'''
array([[100, 1, 2],
[ 5, 6, 7]])
'''
# 原数组也发生了改变
print(X)
'''
array([[100, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[ 10, 11, 12, 13, 14]])
'''
如果我们需要创建一个与原数组不相关的子数组呢?可以使用 .copy()
方法。
subX = X[:2, :3].copy()
print(subX)
'''
array([[0, 1, 2],
[5, 6, 7]])
'''
# 此时再修改子数组
subX[0, 0] = 100
print(subX)
'''
array([[100, 1, 2],
[ 5, 6, 7]])
'''
# 原数组不会发生变化了
print(X)
'''
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
'''
Reshape
通过 reshape 函数修改数组的形状,需要注意调用 reshape 方法是没有改变原数组自身的。
代码语言:javascript复制print(x.shape) # (10,)
print(x.ndim) # 1
print(x.reshape(2, 5))
'''
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
'''
# 没有改变原数组
print(x)
'''
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
'''
# 可以通过使用修改后的数组,可以将其赋值给新变量
A = x.reshape(2, 5)
B = x.reshape(1, 10)
print(B)
'''
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
'''
print(B.ndim) # 2
print(B.shape) # (1, 10)
如果只想指定某个维度,其余维度由程序自动推断,可以使用 -1
代码语言:javascript复制print(x.reshape(10, -1))
'''
array([[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
'''
print(x.reshape(2, -1))
'''
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
'''
# 如果指定3行,其余维度不是整数,会抛出异常
print(x.reshape(3, -1))
'''
ValueError: cannot reshape array of size 10 into shape (3,newaxis)
'''
References:
- Python3入门机器学习 经典算法与应用: https://coding.imooc.com/class/chapter/169.html#Anchor