摘要
以实例为导向,用一种简单易懂的方式介绍Numpy。笔者直接将numpy的方法写入目录,便于查询。
参考文档:
- https://numpy.org/doc/stable/user/index.html
- https://numpy.org/doc/stable/user/absolute_beginners.html
- https://edu.csdn.net/job/pythonbe_02/python-3-195
To:入门Numpy的新手、回顾Numpy的老玩家、急需使用Numpy却无时间系统学习的科研人员
目录
1、入门知识点
1.1、常量
- nan 和Js中的nan一样,只需要注意nan不等于任何数包括它自己
- inf 无穷大
- pi 圆周率
- e 自然常数
这里得注意的是它们有不同的出现方式,比如:inf Inf inf infty Infinity PINF都表示正无穷
1.2、数据类型
numpy 的数值类型实际上是 dtype 对象的实例。
每个内建类型都有一个唯一定义它的字符代码,如下:
字符 | 类型 | 代码 |
---|---|---|
b | boolean | ‘b1’ |
i | signed integer | ‘i1’, ‘i2’, ‘i4’, ‘i8’ |
u | unsigned integer | ‘u1’, ‘u2’ ,‘u4’ ,‘u8’ |
f | floating-point | ‘f2’, ‘f4’, ‘f8’ |
c | complex floating-point | |
m | timedelta64 表示两个时间之间的间隔 | |
M | datetime64 日期时间类型(下有细分) | |
O | object | |
S | (byte-)string S3表示长度为3的字符串 | |
U | Unicode Unicode 字符串 | |
V | void |
a = np.dtype('i8')
print(a.type) # <class 'numpy.int64'>
print(a.itemsize) # 8
值得注意的是python的整数是灵活扩容的,而numpy中的整数是会溢出的
2、实操
2.1、数组创建
ndarray
是python中List的扩展,是numpy中最重要的数据结构。
array
直接将输入的列表转化为nupy.ndarray
类型
asarray
array()
和asarray()
都可以将结构数据转化为 ndarray
,主要区别就是当输入是ndarray
时,array()
仍然会 copy
出一个副本,占用新的内存,但不改变 dtype 时 asarray()
不会。
fromfunction
依据函数和提供的散点维度取出对应坐标
-
参数
-
function 函数
-
shape 散点维度(x,y)
-
**kwargs 一般传入dtype=数据类型
def f(x, y):
return 2 * x + y
x = np.fromfunction(f, (3, 4), dtype=int)
print(x)
# [[0. 1. 2. 3.]
# [2. 3. 4. 5.]
# [4. 5. 6. 7.]]
zeros、ones、empty、full
这部分的加上like表示填充一个和输入同维度的数组
如用零填充,zeros_like
就是创建输入数组的维度并填入0
x = np.zeros(5)
print(x) # [0. 0. 0. 0. 0.]
x = np.zeros([2, 3])
print(x)
# [[0. 0. 0.]
# [0. 0. 0.]]
x = np.full(2, 3)
print(x)
# [3 3]
x = np.full((2, 7), 3)
print(x)
# [[3 3 3 3 3 3 3]
# [3 3 3 3 3 3 3]]
eye、identity
填充一个单位阵,identity表示返回一个方的
diag
提取或者构造对角数组
x = np.arange(9).reshape((3, 3))
print(x)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(np.diag(x)) # [0 4 8]
print(np.diag(x, k=1)) # [1 5]
print(np.diag(x, k=-1)) # [3 7]
v = [1, 2, 3, 4]
x = np.diag(v)
print(x)
# [[1 0 0 0]
# [0 2 0 0]
# [0 0 3 0]
# [0 0 0 4]]
arrange、linspace、logspace、random.rand
给定数值范围创建ndarray
def arange([start,] stop[, step,], dtype=None)
# 起、止、步长
def linspace(start, stop, num=50, endpoint=True,retstep=False, dtype=None,axis=0)
# 起、止、数量
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0)
# 以对数刻度的返回
def rand(d0, d1, ..., dn)
2.2、切片和索引
首先得明白,numpy中的数组在做赋值运算时,返回结果是视图而不是副本。不明白视图和副本分别是什么?看看下面这个代码的运行结果就知道了:
x = np.array([1, 2, 3])
y = x
y[0] = -1
print(x)
# [-1 2 3]
print(y)
# [-1 2 3]
其余的我想也不必多说,与python的列表是一致的。
另外,numpy可以使用...
来表示足够的冒号。
如一个5维数组x中,x[4,...,5,:]
等于 x[4,:,:,5,:]
的含义是一致的。
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]])
r = np.array([[0, 1], [3, 4]])
print(x[r])
# [[[11 12 13 14 15]
# [16 17 18 19 20]]
#
# [[26 27 28 29 30]
# [31 32 33 34 35]]]
y = x > 25
print(y)
# [[False False False False False]
# [False False False False False]
# [False False False False False]
# [ True True True True True]
# [ True True True True True]]
print(x[x > 25])
# [26 27 28 29 30 31 32 33 34 35]
2.3、数组遍历
apply_along_axis
第一个参数是需要执行的函数,第二个参数表示执行的维度
y = np.apply_along_axis(np.sum, 0, x)
print(y) # [105 110 115 120 125]
y = np.apply_along_axis(np.sum, 1, x)
print(y) # [ 65 90 115 140 165]
2.4、数组变形1
变形
-
numpy.ndarray.shape
表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。 -
numpy.ndarray.flat
将数组转换为一维的迭代器,可以用for访问数组每一个元素。 -
numpy.ndarray.flatten([order='C'])
将数组的副本转换为一维数组,并返回。(ravel可以返回视图)- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
order:{'C / F,'A,K}
,可选使用此索引顺序读取a的元素。'C’意味着以行大的C风格顺序对元素进行索引,最后一个轴索引会更改F表示以列大的Fortran样式顺序索引元素,其中第一个索引变化最快,最后一个索引变化最快。请注意,'C’和’F’选项不考虑基础数组的内存布局,仅引用轴索引的顺序.A’表示如果a为Fortran,则以类似Fortran的索引顺序读取元素在内存中连续,否则类似C的顺序。“ K”表示按照步序在内存中的顺序读取元素,但步幅为负时反转数据除外。默认情况下,使用Cindex顺序。
-
numpy.reshape(a, newshape[, order='C'])
在不更改数据的情况下为数组赋予新的形状。 -
numpy.transpose(a, axes=None)
转置 -
numpy.newaxis = None
如果输入数据达不到指定的维度时,可以使用newaxis参数来增加一个维度
x = np.array([1, 2, 9, 4, 5, 6, 7, 8])
print(x.shape) # (8,)
print(x) # [1 2 9 4 5 6 7 8]
y = x[np.newaxis, :]
print(y.shape) # (1, 8)
print(y) # [[1 2 9 4 5 6 7 8]]
y = x[:, np.newaxis]
print(y.shape) # (8, 1)
print(y)
# [[1]
# [2]
# [9]
# [4]
# [5]
# [6]
# [7]
# [8]]
numpy.squeeze(a, axis=None)
从数组的形状中删除单维度条目。
拼接
numpy.concatenate((a1, a2, ...), axis=0, out=None)
连接两个数组
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[7, 8, 9], [10, 11, 12]])
z = np.concatenate([x, y])
print(z)
# [[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]]
z = np.concatenate([x, y], axis=0)
print(z)
# [[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]]
z = np.concatenate([x, y], axis=1)
print(z)
# [[ 1 2 3 7 8 9]
# [ 4 5 6 10 11 12]]
numpy.stack(arrays, axis=0, out=None)
增加维度的拼接
x = np.array([1, 2, 3])
y = np.array([7, 8, 9])
z = np.stack([x, y])
print(z.shape) # (2, 3)
print(z)
# [[1 2 3]
# [7 8 9]]
z = np.stack([x, y], axis=1)
print(z.shape) # (3, 2)
print(z)
# [[1 7]
# [2 8]
# [3 9]]
numpy.vstack(tup)
numpy.hstack(tup)
垂直和水平方向的拼接。在数据维度等于1时,比较特殊。而当维度大于或等于2时,它们的作用相当于concatenate,用于在已有轴上进行操作。numpy.tile(A, reps)
将A作为子矩阵拼接成reps形状numpy.repeat(a, repeats, axis=None)
x = np.array([[1, 2], [3, 4]])
y = np.repeat(x, 2)
print(y)
# [1 1 2 2 3 3 4 4]
y = np.repeat(x, 2, axis=1)
print(y)
# [[1 1 2 2]
# [3 3 4 4]]
y = np.repeat(x, [2, 3], axis=0)
print(y)
# [[1 2]
# [1 2]
# [3 4]
# [3 4]
# [3 4]]
y = np.repeat(x, [2, 3], axis=1)
print(y)
# [[1 1 2 2 2]
# [3 3 4 4 4]]
拆分
numpy.split(ary, indices_or_sections, axis=0)
numpy.vsplit(ary, indices_or_sections)
numpy.hsplit(ary, indices_or_sections)
x = np.array([[11, 12, 13, 14],
[16, 17, 18, 19],
[21, 22, 23, 24]])
y = np.split(x, [1, 3])
print(y)
# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],
# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]
y = np.split(x, [1, 3], axis=1)
print(y)
# [array([[11],
# [16],
# [21]]),
# array([[12, 13],
# [17, 18],
# [22, 23]]),
# array([[14],
# [19],
# [24]])]
参考自之前学习的笔记,有大量当时应该是复制的,暂时没找到出处,特此说明。不过可能原作是英文,那就算是翻译吧哈哈 ↩︎