我是根据官方中文文档,跟着敲的代码,原文地址为https://www.numpy.org.cn/article/basics/an_introduction_to_scientific_python_numpy.html
首先,导入库
import numpy as np
生成ndarray:
首先,np.array()可以传递任何序列,不仅仅是list
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
给定开头结尾,以给定的间隔产生num个数的ndarray。
例:
>>> d = np.linspace(0,2*np.pi,5)
>>> d
array([0. , 1.57079633, 3.14159265, 4.71238898, 6.28318531])
np.arange([start,] stop[, step,], dtype=None)
给定开头结尾,以给定的间隔产生ndarray,但是不包含结尾,与np.linspace的区别是np.arange主要用于整数。
例:
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
多维数组
例:
>>> a = 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]])
>>> a
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]])
可以利用dtype参数指定ndarray数据类型
切片操作:
利用上边的a变量,逗号前边控制行,逗号后边控制列
>>> a[0,1:4]
array([12, 13, 14])
>>> a[1:4,0]
array([16, 21, 26])
>>> a[::2,::2]
array([[11, 13, 15],
[21, 23, 25],
[31, 33, 35]])
>>> a[:,1]
array([12, 17, 22, 27, 32])
数组属性:
依旧使用上边的变量a:
>>> type(a)
<class 'numpy.ndarray'>
>>> a.dtype
dtype('int32')
>>> a.size
25
>>> a.shape
(5, 5)
>>> a.itemsize
4
>>> a.ndim
2
>>> a.nbytes
100
itemsize属性是每个项占用的字节数。这个数组的数据类型是int 32,一个int 32中有32位,一个字节中有4位,除以32除以4,就可以得到它占用了多少字节,在本例中是4。
ndim 属性是数组的维数。这个有2个。例如,向量只有1。
nbytes 属性是数组中的所有数据消耗掉的字节数。应该注意到,这并不计算数组的开销,因此数组占用的实际空间将稍微大一点。
Numpy基本操作符:
>>> a = np.arange(25)
>>> a = a.reshape((5, 5))
>>> b = np.array([10, 62, 1, 14, 2, 56, 79, 2, 1, 45,
4, 92, 5, 55, 63, 43, 35, 6, 53, 24,
56, 3, 56, 44, 78])
>>> b = b.reshape((5,5))
>>> a+b
array([[ 10, 63, 3, 17, 6],
[ 61, 85, 9, 9, 54],
[ 14, 103, 17, 68, 77],
[ 58, 51, 23, 71, 43],
[ 76, 24, 78, 67, 102]])
>>> a-b
array([[-10, -61, 1, -11, 2],
[-51, -73, 5, 7, -36],
[ 6, -81, 7, -42, -49],
[-28, -19, 11, -35, -5],
[-36, 18, -34, -21, -54]])
>>> a*b
array([[ 0, 62, 2, 42, 8],
[ 280, 474, 14, 8, 405],
[ 40, 1012, 60, 715, 882],
[ 645, 560, 102, 954, 456],
[1120, 63, 1232, 1012, 1872]])
>>> a/b
array([[0. , 0.01612903, 2. , 0.21428571, 2. ],
[0.08928571, 0.07594937, 3.5 , 8. , 0.2 ],
[2.5 , 0.11956522, 2.4 , 0.23636364, 0.22222222],
[0.34883721, 0.45714286, 2.83333333, 0.33962264, 0.79166667],
[0.35714286, 7. , 0.39285714, 0.52272727, 0.30769231]])
>>> a>b
array([[False, False, True, False, True],
[False, False, True, True, False],
[ True, False, True, False, False],
[False, False, True, False, False],
[False, True, False, False, False]])
>>> a<b
array([[ True, True, False, True, False],
[ True, True, False, False, True],
[False, True, False, True, True],
[ True, True, False, True, True],
[ True, False, True, True, True]])
数组特殊运算符:
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.sum()
45
>>> a.min()
0
>>> a.max()
9
>>> a.cumsum()
array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45], dtype=int32)
>>>
sum()、min()和max()函数的作用非常明显。将所有元素相加,找出最小和最大元素。
默认情况下,这些操作适用于数组,就好像它是数字列表一样,无论其形状如何。但是,通过指定 axis 参数,可以沿着数组的指定轴应用操作:
>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b.sum(axis=0)
array([12, 15, 18, 21])
>>> b.min(axis=1)
array([0, 4, 8])
>>> b.cumsum(axis=1)
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38]], dtype=int32)
>>>
然而,cumsum()函数就不那么明显了。它将像sum()这样的每个元素相加,但是它首先将第一个元素和第二个元素相加,并将计算结果存储在一个列表中,然后将该结果添加到第三个元素中,然后再将该结果存储在一个列表中。这将对数组中的所有元素执行此操作,并返回作为列表的数组之和的运行总数。
花式索引:
>>> a = np.arange(1,100,10)
>>> a
array([ 1, 11, 21, 31, 41, 51, 61, 71, 81, 91])
>>> indice = [1,5,6,-1]
>>> a[indice]
array([11, 51, 61, 91])
正如你在上面的示例中所看到的,我们使用我们想要检索的特定索引序列对数组进行索引。这反过来返回我们索引的元素的列表。
布尔屏蔽
布尔屏蔽是一个有用的功能,它允许我们根据我们指定的条件检索数组中的元素。
import matplotlib.pyplot as plt
a = np.linspace(0, 2 * np.pi, 50)
b = np.sin(a)
plt.plot(a,b)
mask = b >= 0
plt.plot(a[mask], b[mask], 'bo')
mask = (b >= 0) & (a <= np.pi / 2)
plt.plot(a[mask], b[mask], 'go')
plt.show()
上面的示例显示了如何进行布尔屏蔽。你所要做的就是将数组传递给涉及数组的条件,它将为你提供一个值的数组,为该条件返回true。
缺省索引
>>> a = np.arange(0,100,10)
>>> a
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
>>> b = a[:5]
>>> c = a[a >= 50]
>>> b
array([ 0, 10, 20, 30, 40])
>>> c
array([50, 60, 70, 80, 90])
>>>
这是从一维数组获取切片的简单方法;
Where函数:
>>> a = np.arange(0, 100, 10)
>>> b = np.where(a < 50)
>>> c = np.where(a >= 50)[0]
>>> b
(array([0, 1, 2, 3, 4], dtype=int64),)
>>> c
array([5, 6, 7, 8, 9], dtype=int64)
>>> type(b)
<class 'tuple'>
>>> type(c)
<class 'numpy.ndarray'>
>>> len(c)
5
>>> len(b)
1
np.where返回的是一个元组,但是只有一个元素,如上代码所示。
另一篇,https://www.numpy.org.cn/user_guide/quickstart_tutorial/the_basics.html
几个创建ndarray的函数:
>>> np.zeros((5,6))
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
>>> np.ones((4,5))
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
>>> np.empty((3,4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
函数 zeros 创建一个由0组成的数组,函数 ones 创建一个由1数组的数组,函数 empty 内容是随机的并且取决于存储器的状态。默认情况下,创建的数组的dtype是 float64。
一些需要注意的基础操作:
某些操作(例如+=和*=)适用于修改现有数组,而不是创建新数组。
>>> a = np.ones((2,3),dtype=int)
>>> a
array([[1, 1, 1],
[1, 1, 1]])
>>> b = np.random.random((2,3))
>>> b
array([[0.90877251, 0.36070007, 0.8221808 ],
[0.3020531 , 0.74957915, 0.40888398]])
>>> a *= 3
>>> a
array([[3, 3, 3],
[3, 3, 3]])
>>> b == a
array([[False, False, False],
[False, False, False]])
>>> b += a
>>> b
array([[3.90877251, 3.36070007, 3.8221808 ],
[3.3020531 , 3.74957915, 3.40888398]])
>>> a += b
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
a += b
numpy.core._exceptions.UFuncTypeError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
>>>
当使用不同类型的数组操作时,结果数组的类型对应于更一般或更精确的数组(称为向上转换的行为)。
>>> a = np.ones(3,dtype=np.int32)
>>> b = np.linspace(0,np.pi,3)
>>> b
array([0. , 1.57079633, 3.14159265])
>>> a
array([1, 1, 1])
>>> b.dtype.name
'float64'
>>> c = a + b
>>> c.dtype.name
'float64'
>>> d = np.exp(c * 1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
-0.54030231-0.84147098j])
>>> d.dtype.name
'complex128'
>>>
通用函数:
numpy提供了一些常用的数学函数:
exp,sqrt,add,all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot, vectorize, where
>>> b = np.arange(3)
>>> b
array([0, 1, 2])
>>> np.exp(b)
array([1. , 2.71828183, 7.3890561 ])
>>> np.sqrt(b)
array([0. , 1. , 1.41421356])
>>> np.add(np.exp(b),np.sqrt(b))
array([1. , 3.71828183, 8.80326966])
>>>
多维切片:
>>> def f(x,y):
return 100 * x + y
>>> b = np.fromfunction(f,(5,6),dtype = np.int32)
>>> b
array([[ 0, 1, 2, 3, 4, 5],
[100, 101, 102, 103, 104, 105],
[200, 201, 202, 203, 204, 205],
[300, 301, 302, 303, 304, 305],
[400, 401, 402, 403, 404, 405]])
>>> b[2,3]
203
>>> b[0:5,1]
array([ 1, 101, 201, 301, 401])
>>> b[:,1]
array([ 1, 101, 201, 301, 401])
>>> b[1:3,:]
array([[100, 101, 102, 103, 104, 105],
[200, 201, 202, 203, 204, 205]])
这里的np.fromfunction是把行列坐标作为参数传入函数f中。
当提供比轴数更少的索引时,缺失的索引被认为是一个完整切片 :
>>> b[-2]
array([300, 301, 302, 303, 304, 305])
>>> b[-1]
array([400, 401, 402, 403, 404, 405])
b[i] 方括号中的表达式 i 被视为后面紧跟着 : 的多个实例,用于表示剩余轴。NumPy也允许你使用三个点写为 b[i,…]。
三个点( … )表示产生完整索引元组所需的冒号。例如,如果 x 是rank为的5数组(即,它具有5个轴),则
x[1,2,…] 等于 x[1,2,:,:,:]。
x[…,3] 等效于 x[:,:,:,:,3]。
x[4,…,5,:] 等效于 x[4,:,:,5,:]。
>>> c = np.random.random((2,2,3))
>>> c
array([[[0.63111117, 0.11691753, 0.93938446],
[0.412161 , 0.89472879, 0.56031794]],
[[0.1822608 , 0.30928501, 0.87835717],
[0.38244994, 0.66614506, 0.29709805]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...]
array([[0.1822608 , 0.30928501, 0.87835717],
[0.38244994, 0.66614506, 0.29709805]])
>>> c[...,2]
array([[0.93938446, 0.56031794],
[0.87835717, 0.29709805]])
>>>
迭代:
多维数组是相对于第一个轴完成的:
>>> b
array([[ 0, 1, 2, 3, 4, 5],
[100, 101, 102, 103, 104, 105],
[200, 201, 202, 203, 204, 205],
[300, 301, 302, 303, 304, 305],
[400, 401, 402, 403, 404, 405]])
>>> for r in b:
print(r)
[0 1 2 3 4 5]
[100 101 102 103 104 105]
[200 201 202 203 204 205]
[300 301 302 303 304 305]
[400 401 402 403 404 405]
>>>
但是,如果想要对数组中的每个元素执行操作,可以使用 flat 属性,该属性是数组中所有元素的迭代器:
>>> type(b.flat)
<class 'numpy.flatiter'>
>>> for i in b.flat:
print(i)
0
1
2
3
4
5
100
101
102
103
104
105
200
201
202
203
204
205
300
301
302
303
304
305
400
401
402
403
404
405
>>>