Python-NumPy学习笔记

本文将分五个方面讲解NumPy数组

NumPy提供了两种基本的对象:ndarray和ufunc

ndarray是存储单一数据类型的多维数组,ufunc则是能够对数组进行处理的函数

一、NumPy的导入

import numpy as np

二、创建数组

1、通过array函数

可以通过给array函数传递Python的序列对象创建数组,如果传递的是多层嵌套的序列,将创建多维数组(例如:变量c):

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

dtype:数组的元素类型可以通过dtype属性获得,如 c.dtype

数组的元素类型可以通过dtype属性获得。可以通过dtype属性获得。可以通过dtype参数在创建时指定元素类型,如:

d1=np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10]],dtype=np.float)
d2=np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10]],dtype=np.complex)

运行的结果分别为:


shape:数组的大小可以通过其shape属性获得,如:a.shape。可以通过修改数组的shape属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度,如:c.shape = 4,3(注意从(3,4)改为(4,3)并不是对数组进行转置,只是改变每个轴的大小,数组元素在内存中的位置并没有改变。) c就变成了[[1,2,3],[4,4,5],[6,7,7],[8,9,10]]

c.shape=2,-1 #当某个轴的元素为-1时,将根据数组元素的个数自动计算此轴的长度,因此下面的程序将数组c的shape改为了(2,6)。

reshape:d=a.reshape((2,2)) #使用数组的reshape方法,可以创建一个改变了尺寸的新数组,原数组的shape保持不变。即d变成了

[[1,2],[3,4]],而a还是[1,2,3,4].数组a和d其实共享数据存储内存区域,因此修改其中任意一个数组的元素都会同时修改另外一个数组。如:a[1]=100(将数组a的第2个元素改为100),此时,数组d中的第二个元素也被改变了,变为:[[1,100],[3,4]].


上面的例子都是先创建一个Python序列,然后通过array函数将其转换为数组,这样做效率不高。因此Numpy提供了很多专门用来创建数组的函数。

2、通过NumPy提供的函数

arange函数类似于python中的range函数,通过指定开始值、终值和步长来创建一维数组,注意数组不包括终值

np.arange(0,1,0.1)

结果为:

linspace函数通过指定开始值、终值和元素个数来创建一维数组,可以通过endpoint关键字指定是否包括终值,缺省设置是包括终值

np.linspace(0,1,10) #步长为1/9

结果为:

np.linspace(0,1,10,endpoint=False) # 步长为1/10

结果为:

logspace函数和linspace类似,不过它创建等比数列,下面的例子产生1(10^0)到100(10^2)、有20个元素的等比数列:

np.logspace(0,2,20)

结果为:

zeros()、ones()、empty()可以创建指定形状和类型的数组。

np.empty((2,3),np.int) # 只分配内存,不对其初始化
np.zeros(4,np.float) # 元素类型默认为np.float,因此这里可以省略

    此外,zeros_like()、ones_like()、empty_like()等函数可创建与参数数组的形状及类型相同的数组。因此,'zeros_like(a)'和

'zeros(a.shape,a.dtype)'的效果相同。

    此外,使用frombuffer,fromstring,fromfile,fromfunction等函数可以从字节序列、文件创建数组,下面以fromfunction为例。

def func(i):
    return i%4+1

np.fromfunction(func,(10,))

结果为:

fromfunction函数的第一个参数为计算每个数组元素的函数,第二个参数为数组的大小(shape)。

下面的例子创建一个二维数组表示九九乘法表,输出的数组a中的每个元素a[i,j]都等于func2(i,j):

def func2(i,j):
    return (i+1)*(j+1)

a = np.fromfunction(func2,(9,9))

结果为:

三、存取元素

数组元素的存取方法和Python的标准方法相同:

a = np.arange(10)

a[5] # 用整数作为下标可以获取数组中的某个元素

a[3:5],结果为[3,4] # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]

a[:5],结果为[0,1,2,3,4] # 省略开始下标,表示从a[0]开始

a[:-1],结果为[0,1,2,3,4,5,6,7,8] # 下标可以使用负数,表示从数组后往前数

a[2:4] = 100,101,结果为[0,1,100,101,4,5,6,7,8,9] # 下标还可以用来修改元素的值

a[1:-1:2],结果为[1,101,5,7] # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素

a[::-1],结果为[9,8,7,6,5,4,101,100,1,0] # 省略范围的开始下标和结束下标,步长为-1,整个数组头尾颠倒

a[5:1:-2],结果为[5,101] # 步长为负数时,开始下标必须大于结束下标

和Python的列表序列不同,通过下标范围获取的新的数组是原始数组的一个视图。它与原始数组共享同一块数据空间:

b = a[3:7] ,结果为[101,4,5,6]# 通过下标范围产生一个新的数组b,b和a共享同一块数据空间

b[2] = -10,结果为[101,4,-10,6]# 将b的第3个元素修改为-10,此时a为[0,1,100,101,4,-10,6,7,8,9]

    除了使用下标范围存取元素之外,NumPy还提供了两种存取元素的高级方法。

  • 使用整数序列

    当使用整数序列对数组元素进行存取时,将使用整数序列中的每个元素作为下标,整数序列可以使列表或者数组,使用整数序列作为下标获得的数组不和原始数组共享数据空间。

x = np.arange(10,1,-1) # x为[10,9,8,7,6,5,4,3,2]
x[[3,3,1,8]],结果为[7,7,9,2] # 获取x中的下标为3,3,1,8的4个元素,组成一个新的数组

b = x[np.array([3,3,-3,8])] # 下标可以使负数

b[2]=100,b变为[7,7,100,2],此时x依旧为[10,9,8,7,6,5,4,3,2],由于b和x不共享数据空间,因此x中的值没有改变

x[[3,5,1]] = -1,-2,-3 # 整数序列下标也可以用来修改元素的值,x变为[10,-3,8,-1,6,-2,4,3,2]

  • 使用布尔数组
    当使用布尔数组b作为下标存取数组x中的元素时,将收集数组x中所有在数组b中对应下标为True的元素。使用布尔数组作为下标获得的数组 不和原始数组共享数据空间, 注意这种方式只对应于布尔数组,不能使用布尔列表
x = np.arange(5,0,-1) # x为[5,4,3,2,1]

x[np.array([True,False,True,False,False])],结果为[5,3] # 布尔数组中下标为0,2的元素为True,因此获取x中下标为0,2的元素

x[[True,False,True,False,False]],结果为[5,3] # 如果是布尔列表,下标0,2的元素为True,因此获取x中下标为0,2的元素

x[np.array([True,False,Ture,True,False])] = -1,-2,-3 ,x变为[-1,4,-2,-3,1]# 布尔数组下标也可以用来修改元素


四、多维数组

    多维数组的存取和一维数组类似,因为多维数组有多个轴,因此它的下标需要用多个值来表示,NumPy采用组元(tuple)

作为数组的下标。





五、结构数组

    假设需要定义一个结构数组,它的每个元素都有name,age和weigh字段。在NumPy中可以如下定义:



猜你喜欢

转载自blog.csdn.net/qq_37676636/article/details/80850169