NumPy是Python的一个线性代数库,在数据科学研究和学习中扮演很重要的角色,这篇文章将带大家学习一些常用的功能,并且教会大家如何参考NumPy API。
安装
如何安装我就不详细说了,建议大家安装一个Python的集成安装管理器,比如Anacoda。 我使用的是Enthought Canopy这个集成了jupyter notebook 和其他的一些Python 安装包和库,很方便。
使用NumPy
通过以下命令导入:
import numpy as np
Numpy Arrays
通过Numpy 可以建立一维或多维数组,矩阵。
-
通过List建立数组
list和array是有区别的,List只是一些对象的集合,但是Array是一种数据结构。
我们可以先建立一个List,然后将List数组化。
my_list = [1,2,3] # 一维数组
my_list
np.array(my_list)
my_matrix = [[1,2,3],[4,5,6],[7,8,9]] # 矩阵
my_matrix
np.array(my_matrix)
-
通过内置方法建立数组(Build-In)
- arange
arange 方法返回一个间隔均匀的值,常用的包含三个参数:起始位置(start),结束位置(end),间隔(step)。其中结束位置不包含进返回值,这与linspace不同。起始位置默认为0,间隔默认为1。故arange可以只有一个或两个参数。
np.arange(10)
np.arange(0,10)
np.arange(0,10,1) # 以上三组返回同一个数组
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
- zero and ones
返回全是0 或者全是 1 的数组
np.zeros(3)
output: array([ 0., 0., 0.])
np.zeros((5,5)) # 注意,若想返回多维数组必须用双括号
output: 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.]])
np.ones(3)
output: array([ 1., 1., 1.])
np.ones((3,3))
output: array([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
同样可以对这些数组进行算数运算操作
np.ones(5) * 5
output: array([ 5., 5., 5., 5., 5.])
- linspace
linspace 与arange很相似,同样有三个参数,前两个相同,都是起始和结束。arange返回数组中每个元素间隔步数相同。但是linspace返回数组是均分起始和结束位置之间的步数。要注意两点,一是最后一个参数不是间隔,而是要返回数组内对象的个数。二是arange中结束位置不包括在返回数组中,但是linspace需要包括结束位置。此外,linspace起始和结束没有默认值,所以参数必须要有,但是第三个均分数的默认值是50。
np.linspace(0,10,3)
output: array([ 0., 5., 10.])
np.linspace(0,10,50)
output: array([ 0. , 0.20408163, 0.40816327, 0.6122449 ,
0.81632653, 1.02040816, 1.2244898 , 1.42857143,
1.63265306, 1.83673469, 2.04081633, 2.24489796,
2.44897959, 2.65306122, 2.85714286, 3.06122449,
3.26530612, 3.46938776, 3.67346939, 3.87755102,
4.08163265, 4.28571429, 4.48979592, 4.69387755,
4.89795918, 5.10204082, 5.30612245, 5.51020408,
5.71428571, 5.91836735, 6.12244898, 6.32653061,
6.53061224, 6.73469388, 6.93877551, 7.14285714,
7.34693878, 7.55102041, 7.75510204, 7.95918367,
8.16326531, 8.36734694, 8.57142857, 8.7755102 ,
8.97959184, 9.18367347, 9.3877551 , 9.59183673,
9.79591837, 10. ])
np.linspace(0,9.8) # 只包含两个参数
output: array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8, 2. ,
2.2, 2.4, 2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. , 4.2,
4.4, 4.6, 4.8, 5. , 5.2, 5.4, 5.6, 5.8, 6. , 6.2, 6.4,
6.6, 6.8, 7. , 7.2, 7.4, 7.6, 7.8, 8. , 8.2, 8.4, 8.6,
8.8, 9. , 9.2, 9.4, 9.6, 9.8])
eye
返回一个单位矩阵
np.eye(4)
output: array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
Random 随机数组
Numpy 有返回随机数组的方法:
- rand
返回一个[0,1)符合均匀分布的数组
np.random.rand(2)
output: array([ 0.11570539, 0.35279769])
np.random.rand(5,5)
output: array([[ 0.66660768, 0.87589888, 0.12421056, 0.65074126, 0.60260888],
[ 0.70027668, 0.85572434, 0.8464595 , 0.2735416 , 0.10955384],
[ 0.0670566 , 0.83267738, 0.9082729 , 0.58249129, 0.12305748],
[ 0.27948423, 0.66422017, 0.95639833, 0.34238788, 0.9578872 ],
[ 0.72155386, 0.3035422 , 0.85249683, 0.30414307, 0.79718816]])
- randn
返回一个符合正态分布的数组,这个最常用。
np.random.randn(2)
output:array([-0.27954018, 0.90078368])
np.random.randn(5,5)
output: array([[ 0.70154515, 0.22441999, 1.33563186, 0.82872577, -0.28247509],
[ 0.64489788, 0.61815094, -0.81693168, -0.30102424, -0.29030574],
[ 0.8695976 , 0.413755 , 2.20047208, 0.17955692, -0.82159344],
[ 0.59264235, 1.29869894, -1.18870241, 0.11590888, -0.09181687],
[-0.96924265, -1.62888685, -2.05787102, -0.29705576, 0.68915542]])
- randint
返回从起始到结束结束(不包括)内的随机数,有三个参数:起始(默认为0),结束,个数(默认为1)。
np.random.randint(1,100)
output: 1
np.random.randint(1,100,10)
output: array([13, 64, 27, 63, 46, 68, 92, 10, 58, 24])
- random_sample
返回[0,1) 之间的浮点数。只能有一个参数,就是浮点数的个数。所以返回的只能是一维数组
np.random.random_sample(10)
output: array([ 0.48841451, 0.03582229, 0.16994016, 0.03470048, 0.88780897,
0.43945763, 0.94294373, 0.86339326, 0.64528844, 0.9673806 ])
Array的属性和方法(Array Attributes and Methods)
arr = np.arange(25)
ranarr = np.random.randint(0,50,10)
arr
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24])
ranarr
array([10, 12, 41, 17, 49, 2, 46, 3, 19, 39])
Reshape
返回不同维度但是含有相同元素数目的数组。注意,所包含元素数目必须相同,如果不同会报错。比如一个包含10个元素的一维数组可以重新写成 2x5 或者5x2的数组
arr.reshape(5,5)
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
max,min,argmax,argmin
这四个方法反别返回数组中的最大值,最小值,最大值的位置(index),最小值的位置。
ranarr
array([10, 12, 41, 17, 49, 2, 46, 3, 19, 39])
ranarr.max()
49
ranarr.argmax()
4
ranarr.min()
2
ranarr.argmin()
5
Shape
shape 是数组拥有的属性。由外向内返回数组的size,即每一层包含元素的个数。
# Vector
arr.shape
(25,)
# 这是返回一个包含一个元素的二维数组,若想返回一维数组只需要 arr.reshape(25)
arr.reshape(1,25)
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24]])
arr.reshape(1,25).shape
(1, 25)
arr.reshape(25,1).shape
(25, 1)
dtype
返回数据类型
arr.dtype
dtype('int64')
NumPy 索引与选择(Indexing and Selection)
这段我们来讨论如何从数组中选择元素和设置index
import numpy as np
#Creating sample array
arr = np.arange(0,11)
#Show
arr
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
用中括号来选择
#Get a value at an index
arr[8]
8
#Get values in a range
arr[1:5]
array([1, 2, 3, 4])
#Get values in a range
arr[0:5]
array([0, 1, 2, 3, 4])
Broadcasting
这个功能可以打包改变数组内元素。
#Setting a value with index range (Broadcasting)
arr[0:5]=100
#Show
arr
array([100, 100, 100, 100, 100, 5, 6, 7, 8, 9, 10])
# Reset array, we'll see why I had to reset in a moment
arr = np.arange(0,11)
#Show
arr
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
#Important notes on Slices
slice_of_arr = arr[0:6]
#Show slice
slice_of_arr
array([0, 1, 2, 3, 4, 5])
#Change Slice
slice_of_arr[:]=99
#Show Slice again
slice_of_arr
array([99, 99, 99, 99, 99, 99])
现在来看看原数组值有何变化
arr
array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10])
其实这有点像Java 中传值和传参的区别,当我们将数组的一部分赋值给另一个变量时候,这个变量的改变会影响到原数组的改变。如果我们不想这样,可以用copy()方法,相当于将数组的一部分复制给另一个变量使用,这个变量与原数组将没有关系。
#To get a copy, need to be explicit
arr_copy = arr.copy()
arr_copy
array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10])
Indexing a 2D array (matrices)
如何寻找矩阵中元素
arr_2d[row][col] or arr_2d[row,col]
这样就OK啦~~简单吧!!!
arr_2d = np.array(([5,10,15],[20,25,30],[35,40,45]))
#Show
arr_2d
array([[ 5, 10, 15],
[20, 25, 30],
[35, 40, 45]])
#Indexing row
arr_2d[1]
# Format is arr_2d[row][col] or arr_2d[row,col]
# Getting individual element value
arr_2d[1][0]
20
# 2D array slicing
#Shape (2,2) from top right corner
arr_2d[:2,1:]
array([[10, 15],
[25, 30]])
#Shape bottom row
arr_2d[2]
array([35, 40, 45])
#Shape bottom row
arr_2d[2,:]
array([35, 40, 45])
Fancy Indexing
这里的一些方法可以对数组或者表进行操作。
#Set up matrix
arr2d = np.zeros((10,10))
#Length of array
arr_length = arr2d.shape[1]
#Set up array
for i in range(arr_length):
arr2d[i] = i
arr2d
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.],
[ 8., 8., 8., 8., 8., 8., 8., 8., 8., 8.],
[ 9., 9., 9., 9., 9., 9., 9., 9., 9., 9.]])
可以选择不用列,注意用两个中括号。
arr2d[[2,4,6,8]]
array([[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 8., 8., 8., 8., 8., 8., 8., 8., 8., 8.]])
#Allows in any order
arr2d[[6,4,2,7]]
array([[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.]])
选择(Selection)
可以通过选择进行一些分类操作
arr = np.arange(1,11)
arr
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
bool_arr = arr>4
bool_arr
array([False, False, False, False, True, True, True, True, True, True], dtype=bool)
arr[bool_arr]
array([ 5, 6, 7, 8, 9, 10])
x = 2
arr[arr>x]
array([ 3, 4, 5, 6, 7, 8, 9, 10])
操作(NumPy Operations)
Numpy也有加减乘除等运算操作。
算术运算(Arithmetic)
import numpy as np
arr = np.arange(0,10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
NumPy可以对两个数组或者数组与数值进行加,减,乘运算。
arr + 2
array([ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
arr + arr
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
arr * arr
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81])
arr - arr
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
除法要特别注意:数组除以0不会报错,结果为无穷(inf),但是会抛出警告。0除以0 同样会有警告,结果为0.
# Warning on division by zero, but not an error!
# Just replaced with nan
arr/arr
array([0, 1, 1, 1, 1, 1, 1, 1, 1, 1])
# Also warning, but not an error instead infinity
1/arr
array([ inf, 1. , 0.5 , 0.33333333, 0.25 ,
0.2 , 0.16666667, 0.14285714, 0.125 , 0.11111111])
arr2 = np.zeros(10) # you can get an inf value when you divide by a zeros array
arr/arr2
array([ nan, inf, inf, inf, inf, inf, inf, inf, inf, inf])
arr/0 # but you only get 0 value when you divide by 0.
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
同样可以进行幂运算
arr**3
array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729])
全局方程(Universal Array Functions)
开方:
#Taking Square Roots
np.sqrt(arr)
array([ 0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
e的指数运算:
#Calcualting exponential (e^)
np.exp(arr)
array([ 1.00000000e+00, 2.71828183e+00, 7.38905610e+00,
2.00855369e+01, 5.45981500e+01, 1.48413159e+02,
4.03428793e+02, 1.09663316e+03, 2.98095799e+03,
8.10308393e+03])
最大值:
np.max(arr) #same as arr.max()
9
三角函数:
np.sin(arr)
array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ,
-0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])
对数运算:
np.log(arr)
array([ -inf, 0. , 0.69314718, 1.09861229, 1.38629436,
1.60943791, 1.79175947, 1.94591015, 2.07944154, 2.19722458])