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)

  1. 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])
  1. 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.])
  1. 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])