简介NumPy是一个开源的Python库,主要用于数据分析和科学计算。基本上,NumPy可以算是Python数据计算的基础,因为很多优秀的数据分析和机器学习的底层框架都使用了NumPy。例如:Pandas、SciPy、Matplotlib、scikit-learn、scikit-image等。NumPy库主要包含多维数组和矩阵数据结构。它为ndarray(一个n维数组对象)提供了对其高效操作的方法。NumPy可用于对数组执行各种数学运算。并提供了一个庞大的高级数学函数库,可以对这些数组和矩阵进行操作。根据NumPy安装NumPy的方法有很多种:pipinstallnumpy如果你使用的是conda,那么你可以:condainstallnumpy或者直接使用Anaconda。它是一系列数据分析包的集合。Array和ListPython有一种叫做List的数据类型,可以存储不同种类的对象。在应用程序中这样做没有错,但是如果是在科学计算中,我们希望数组中的元素类型必须一致,所以NumPy中就有了Array。NumPy可以快速创建数组并对其中的数据进行操作。NumPy中的数组比Python中的列表快得多,占用的内存空间也更少。看看两者的性能差异:In[1]:importnumpyasnp...:my_arr=np.arange(1000000)...:my_list=list(range(1000000))...:%timefor_inrange(10):my_arr2=my_arr*2...:%timefor_inrange(10):my_list2=[x*2forxinmy_list]...:CPUtimes:user12.3ms,sys:7.88ms,total:20.2msWalltime:21.4msCPUtimes:user580ms,sys:172ms,total:752msWalltime:780ms上面的例子将一个包含一百万的数据乘以2,可以看到,使用效率NumPy是Python的几十倍。这种效率如果用在大数据项目中,会对性能造成非常大的影响。创建数组在上面的示例中,我们使用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也可以通过索引访问:>>>print(a[0])[1234]接下来介绍几个常用的名词:vector——表示一维数组matrix——表示二维数组张量——表示三维或更高维维度数组的维度在NumPy中也称为轴。让我们看看其他几种创建Array的方法:最简单的是np.array,我们在前面的例子中已经提到过。如果我们想快速创建一个0数组,我们可以使用零:>>>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方法中的内容isnot不一定是空的,而是随机填充了数据,所以我们在使用empty创建数组后,一定要记得覆盖它的内容。使用empty的好处是创建速度更快。也可以在范围内填充数组: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])数组操作sortus数组可以使用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是一种间接排序方法,它返回排序后的原始数组的索引:In[11]:x=np.array([10,5,6])In[12]:np.argsort(x)Out[12]:array([1,2,0])上面我们对数组进行==argsort==,排序后应该返回5,6,10。5的索引为1,6的索引为2,10的索引为0,所以返回1,2,0。==lexsort==和argsort一样,是间接排序方式,返回的是排序索引。区别在于lexsort可以按多个键排序。姓氏=('赫兹','伽利略','赫兹')first_names=('海因里希','伽利略','古斯塔夫')ind=np.lexsort((first_names,姓氏))indarray([1,2,0])上面的lexsort是先按surnames排序,再按first_names排序。lexsort的排序顺序是从后到前。即,最后传入的键最先排序。==searchsorted==用于查找要插入的元素的索引值,例如: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])concatenateconcatenate用于连接多个数组。>>>a=np.数组([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.ndim3ndarray.size用于统计数组中的元素个数:>>>array_example.size24ndarray.shape输出数组的形状:>>>>array_example.shape(3,2,4)表明上面的数组是一个324的数组。reshape使用reshape重建数组。>>>a=np.arange(6)>>>print(a)[012345]>>>b=a.reshape(3,2)>>>print(b)[[01][23][45]]上面我们将一个一维数组转换成了一个3*2的数组。reshape也可以接受多个参数:>>>numpy.reshape(a,newshape=(1,6),order='C')array([[0,1,2,3,4,5]])thOne参数是要重构的数组,第二个参数是新的shape,order可以取三个值,C,F或者A。C表示按照C的索引方式排序,F表示按照索引方式排序的语言。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来指定轴的位置:>>>b=np.expand_dims(a,axis=1)>>>b.shape(6,1)>>>c=np.expand_dims(a,axis=0)>>>c.shape(1,6)索引和切片数组的索引和切片类似于Python中的列表:>>>data=np.array([1,2,3])>>>data[1]2>>>数据[0:2]数组([1,2])>>>数据[1:]数组([2,3])>>>数据[-2:]数组([2,3])此外,数组还支持更强大的索引操作:>>>a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])>>>print(a[a<5])[1234]上面我们找出a中所有小于5的元素的值。在[20]:a<5Out[20]:array([[True,True,True,True],[False,False,False,False],[False,False,False,False]])可以看到一个<5其实返回的也是一个数组。这个数组的元素形状和原来的数组一样,但是里面的值是true和false,表示是否应该被选中。同理,我们可以把所有大于5的元素都挑出来:>>>five_up=(a>=5)>>>print(a[five_up])[56789101112]选择所有可以选择的元素被2整除的数:>>>divisible_by_2=a[a%2==0]>>>print(divisible_by_2)[24681012]你也可以使用&和|operators:>>>c=a[(a>2)&(a<11)]>>>print(c)[345678910]也可以使用nonzero打印出索引信息满足条件:在[23]中:a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])在[24]中:b=np.非零(a<5)In[25]:bOut[25]:(array([0,0,0,0]),array([0,1,2,3]))>>>print(a[b])[1234]在上面返回的元组中,第一个值代表行号,第二个值代表列。
