简介

NumPy是一个开源的Python库,次要用在数据分析和科学计算,基本上能够把NumPy看做是Python数据计算的根底,因为很多十分优良的数据分析和机器学习框架底层应用的都是NumPy。比方:Pandas, SciPy, Matplotlib, scikit-learn, scikit-image 等。

NumPy库次要蕴含多维数组和矩阵数据结构。 它为ndarray(一个n维数组对象)提供了对其进行无效操作的办法。 NumPy能够用于对数组执行各种数学运算。 并且提供了可在这些数组和矩阵上运行的宏大的高级数学函数库。

装置NumPy

有很多形式能够依照NumPy:

pip install numpy

如果你应用的是conda,那么能够:

conda install numpy

或者间接应用Anaconda. 它是一系列数据分析包的汇合。
Array和List
Python中有一个数据类型叫做List,list中能够存储不同品种的对象。在应用程序中这样做没有什么问题,然而如果是在科学计算中,咱们心愿一个数组中的元素类型必须是统一的,所以有了NumPy中的Array。

NumPy能够疾速的创立Array,并且对其中的数据进行操作。

NumPy中的Array要比Python中的List要快得多,并且占用更少的内存空间。

看下两者之间的性能差别:

In [1]: import numpy as np   ...: my_arr = np.arange(1000000)   ...: my_list = list(range(1000000))   ...: %time for _ in range(10): my_arr2 = my_arr * 2   ...: %time for _ in range(10): my_list2 = [x * 2 for x in my_list]   ...:CPU times: user 12.3 ms, sys: 7.88 ms, total: 20.2 msWall time: 21.4 msCPU times: user 580 ms, sys: 172 ms, total: 752 msWall time: 780 ms

下面的例子对一个蕴含一百万的数据进行乘2操作,能够看到,应用NumPy的效率是Python的几十倍,如果在大型数据我的项目中这个效率会造成十分大的性能影响。

创立Array

下面的例子中,咱们曾经创立了一个array,应用的是np.arange办法。

咱们还能够通过List来创立Array,List能够是一维列表,也能够是多维列表:

>>> a = np.array([1, 2, 3, 4, 5, 6])>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

和List一样,Array也能够通过index来拜访:

>>> print(a[0])[1 2 3 4]

接下来咱们介绍几个罕用的名词:

  • vector — 示意的是一维数组
  • matrix — 示意的是二维数组
  • tensor — 示意的是三维或者更高维度的数组

在NumPy中维度也被称之为 axes 。
上面咱们来看下其余几种创立Array的办法:
最简略的就是np.array,之前的例子中咱们曾经提到过了。
如果要疾速的创立都是0 的数组,咱们能够应用zeros:

>>> np.zeros(2)array([0., 0.])

或者都填充为1:

>>> np.ones(2)array([1., 1.])

还能够创立空的数组:

In [2]: np.empty(2)Out[2]: array([0.        , 2.00389455])

留神,empty办法中的内容并不一定是空的,而是随机填充数据,所以咱们在应用empty创立数组之后,肯定要记得笼罩其中的内容。应用empty的益处就是创立的速度比拟快。

还能够在range范畴内填充数组:

In [3]: np.arange(10)Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

能够指定距离:

In [4]: np.arange(1,10,2)Out[4]: array([1, 3, 5, 7, 9])

应用linspace能够创立等分的数组:

In [5]: np.linspace(0, 10, num=5)Out[5]: array([ 0. ,  2.5,  5. ,  7.5, 10. ])

默认状况下创立的数组内容类型是np.float64,咱们还能够将其切换成整数:

np.int64In [6]: x = np.ones(2, dtype=np.int64)In [7]: xOut[7]: array([1, 1])

Array操作
sort
咱们能够应用sort对数组进行排序:

In [8]: arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])In [10]: np.sort(arr)Out[10]: array([1, 2, 3, 4, 5, 6, 7, 8])

==sort==是对Array中的元素进行排序, 除了sort之外还有其余的一些排序的办法。
还能够应用argsort,argsort是一种间接排序的办法,他返回的是排序好的原数组的index:

In [11]: x = np.array([10, 5, 6])In [12]: np.argsort(x)Out[12]: array([1, 2, 0])

下面咱们对array进行==argsort==,排序之后应该返回,5,6,10。 5的index是1,6 的index是2,10的index是0,所以返回1,2,0。
==lexsort==和argsort一样都是间接排序法,返回的都是排序过后的index,不同是lexsort 能够进行多key的排序。

surnames =    ('Hertz',    'Galilei', 'Hertz')first_names = ('Heinrich', 'Galileo', 'Gustav')ind = np.lexsort((first_names, surnames))indarray([1, 2, 0])

下面的lexsort是先依照surnames排序,而后再依照first_names进行排序。

lexsort 的排序程序是从后到前。也就是最初一个传入的key最先排序。

==searchsorted==用来查找要插入元素的index值,举个例子:

np.searchsorted([1,2,3,4,5], 3)2np.searchsorted([1,2,3,4,5], 3, side='right')3np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])array([0, 5, 1, 2])

==partition==是对要排序的数据进行宰割,举个例子:

a = np.array([3, 4, 2, 1])np.partition(a, 3)array([2, 1, 3, 4])

第一个参数是一个Array,第二个参数是要分隔的基准元素,这个基准元素的地位和排序过后的地位是一样的,其余的元素比基准元素小的放在后面,比基准元素大的放在前面。
还能够依照多个元素进行宰割:

np.partition(a, (1, 3))array([1, 2, 3, 4])

concatenate
concatenate用来连贯多个数组。

>>> a = np.array([1, 2, 3, 4])>>> b = np.array([5, 6, 7, 8])>>> np.concatenate((a, b))array([1, 2, 3, 4, 5, 6, 7, 8])

还能够连贯多维数组:

>>> x = np.array([[1, 2], [3, 4]])>>> y = np.array([[5, 6]])>>> np.concatenate((x, y), axis=0)array([[1, 2],       [3, 4],       [5, 6]])

统计信息
ndarray.ndim 用来统计数组的维数:

>>> array_example = np.array([[[0, 1, 2, 3],...                            [4, 5, 6, 7]],......                           [[0, 1, 2, 3],...                            [4, 5, 6, 7]],......                           [[0 ,1 ,2, 3],...                            [4, 5, 6, 7]]])
>>> array_example.ndim3

ndarray.size 用来统计数组中的元素个数:

>>> array_example.size24

ndarray.shape 输入数组的形态:

>>> array_example.shape(3, 2, 4)

阐明下面的数组是一个3 2 4 的数组。
reshape
应用reshape能够从新结构一个数组。

>>> a = np.arange(6)>>> print(a)[0 1 2 3 4 5]>>> b = a.reshape(3, 2)>>> print(b)[[0 1] [2 3] [4 5]]

下面咱们将一个一维的数组转成了一个3* 2 的数组。
reshape还能够承受多个参数:

>>> numpy.reshape(a, newshape=(1, 6), order='C')array([[0, 1, 2, 3, 4, 5]])

第一个参数是要重构的数组,第二个参数新的shape,order能够取三个值,C,F或者A。
C示意依照C的index形式进行排序,F示意依照Fortran的index形式进行排序。A示意主动抉择。
在Fortran中,当挪动存储在内存中的二维数组的元素时,第一个索引是变动最快的索引。 当第一个索引更改时挪动到下一行时,矩阵一次存储一列。另一方面,在C中,最初一个索引变动最快。
减少维度
np.newaxis能够给现有的数组减少一个维度:

>>> a = np.array([1, 2, 3, 4, 5, 6])>>> a.shape(6,)>>> a2 = a[np.newaxis, :]>>> a2.shape(1, 6)>>> col_vector = a[:, np.newaxis]>>> col_vector.shape(6, 1)

还能够应用expand_dims来指定axis的地位:

>>> b = np.expand_dims(a, axis=1)>>> b.shape(6, 1)>>> c = np.expand_dims(a, axis=0)>>> c.shape(1, 6)

index和切片
数组的index和切片跟Python中的list是相似的:

>>> data = np.array([1, 2, 3])>>> data[1]2>>> data[0:2]array([1, 2])>>> data[1:]array([2, 3])>>> data[-2:]array([2, 3])

除此之外,数组还反对更多更弱小的index操作:

>>> a = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])>>> print(a[a < 5])[1 2 3 4]

下面咱们找出了a中所有元素小于5的值。

In [20]: a<5Out[20]:array([[ True,  True,  True,  True],       [False, False, False, False],       [False, False, False, False]])

能够看到a< 5 其实返回的也是一个数组,这个数组的元素shape和原数组是一样的,只不过外面的值是true和false,示意是否应该被抉择进去。
同样的,咱们能够挑出所有大于5的元素:

>>> five_up = (a >= 5)>>> print(a[five_up])[ 5  6  7  8  9 10 11 12]

选出所有能够被2整除的数:

>>> divisible_by_2 = a[a%2==0]>>> print(divisible_by_2)[ 2  4  6  8 10 12]

还能够应用 & 和 | 运算符:

>>> c = a[(a > 2) & (a < 11)]>>> print(c)[ 3  4  5  6  7  8  9 10]

还能够应用nonzero来打印出满足条件的index信息:

In [23]: a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])In [24]: b = np.nonzero(a < 5)In [25]: bOut[25]: (array([0, 0, 0, 0]), array([0, 1, 2, 3]))  >>> print(a[b])[1 2 3 4]

下面返回的元组中,第一个值示意的是行号,第二个值示意的是列。