python列表和Numpy数组的区别

Table of Contents

 

python列表和Numpy数组的区别

array的创建

元素访问

array的一维数组的访问方式

array的二维数组的访问方式

参考链接


python列表和Numpy数组的区别

1二者都可以用于处理多维数组。

Numpy中的ndarray对象用于处理多维数组,它作为一个快速而灵活的大数据容器。Python列表可以存储一维数组,通过列表的嵌套可以实现多维数组。

2存储效率和输入输出性能不同。

Numpy专门针对数组的操作和运算进行了设计,存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。

3元素数据类型。

通常,Numpy数组中的所有元素的类型都必须相同的,而Python列表中的元素类型是任意的,所以在通用性能方面Numpy数组不及Python列表,但在科学计算中,可以省掉很多循环语句,代码使用方面比Python列表简单的多。

 

array的创建

Numpy数组创建时,参数既可以是list,也可以是元组。例如:

>>> a=np.array((1,2,3))#参数是tuple

>>> b=np.array([6,7,8])#参数是list

>>> c=np.array([[1,2,3],[4,5,6]])#参数是二维list

除此之外,还可以使用numpy提供的其他方法创建一个数组,例如:

>>> arr1=np.arange(1,10,1)

>>> arr2=np.linspace(1,10,10)

np.arange(a,b,c)表示产生从a-b不包括b,间隔为c的一个array,数据类型默认是int32。但是linspace(a,b,c)表示的是把a-b平均分成c分,它包括b。

今天读程序关于步长的运用:

['%x' %int(''.join(avg_list[x:x+4]),2) for x in range(0,32*32,4)]

这个是感知哈希算法的一个步骤,将二进制数据改写为十六进制,以便于下一步的判断。这里我的一个二进制数据的长度是32×32,且二进制转十六进制可以每隔4位来转,所以就可以将步长设置为4.

从函数规则创建数组也非常方便,numpy的fromfunction函数可以实现这个功能:

>>> def f(x,y):

... return 10*x+y

... b=np.fromfunction(f,(2,2))

该函数的具体内容如下:

 

参数

 

function:

第一个参数是一个函数,例如上例中给出的f。

这个函数接受了N个参数,每个参数表示沿特定轴变化的阵列的坐标。例如上例中,第二个参数(2,2),那么这N个参数就是:(0,0)(0,1)(1,0)(1,1)。

 

shape:

第二个参数是一个元组,表示了数组的大小。

 

dtype:

第三个参数决定了传递给函数的数据类型,默认为浮点型。

 

 

返回值

 

返回一个数组。

 

元素访问

array的一维数组的访问方式

定义一个一维数组,

arr=np.array([0,1,2,3,4,5,6,7,8,9])

arr[5]

访问第6个元素

#结果:5

arr[3:5]

访问第4-5个元素

#结果:array([3,4])

arr[:5]

访问前5元素

#结果:array([0,1,2,3,4])

arr[:-1]

访问除了最后一个元素之外的元素

#结果:array([0,1,2,3,4,5,6,7,8])

arr[:]

访问全部

#结果:array([0,1,2,3,4,5,6,7,8,9])

arr[2:4]=100

将3-4个元素置为100

#结果:array([0,1,100,100,4,5,6,7,8,9])

arr[1:-1:2]

访问从第一个到最后一个的元素,步长为2

#结果:array([1,100,5,7])

arr[::-1]

访问从第一个到最后一个的元素,步长为-1

#结果:array([9,8,7,6,5,4,100,100,1,0])

 

其中,arr[a:b:n]表示按步长为n取从a到b的元素,当n为-1的时候,从右向左访问。

array的二维数组的访问方式

对于二维数组arr=np.array([[1,2,3],[4,5,6]]),我们可以通过一下的方式访问:

arr[1:2]

返回第一行

#结果:[[1,2,3]]

arr[1:2][0]

返回第一行

#结果:[1,2,3]

arr[1]

返回第一行

#结果:[1,2,3]

以上的语句都返回了二维数组的第一行,但是凡是通过“:”访问的,最终都在外面加了“[ ]”,可以像第2语句那样,再用一个索引得到最终的结果。

这里,我想起来最近截取图片的一个例子。

通常,我们用imread的图片就保存在一个数组对象中,例如:img=[[0,1,2], [3,4,5],[6,7,8]].现在我想截取这个图片的(0,0)到(1,1)矩形区域,可以通过下面的语句完成:img[0:1,0:1].截取下的结果就是[[0,1],[3,4]].

另外,还有一个需要注意的点:array的索引最终产生的是一个「 原始数据的浅拷贝」,他和原始数据共用一块内存。

>>> import numpy as np

>>> a=np.array([0,1,2])

>>> b=a[:2]

>>> b

array([0, 1])

>>> b[0]=100

>>> b

array([100, 1])

>>> a

array([100, 1, 2])

当我们修改了b的第一个元素的时候,a的第一个元素也被修改了。因为他们都是指向的同一个内存。

这是因为当我们执行b=a[:2]等语句的时候,拷贝的是指向这个元素的指针,当我们想要修改的时候,也是修改了指针指向的元素值。
 

>>> a=[0,1,2]

>>> b=a[:2]

>>> b

[0, 1]

>>> b[0]=100

>>> b

[100, 1]

>>> a

[0, 1, 2]

与之不同的是,list对象在执行的时候拷贝了数据与指针,就不会有这种状况啦。

除了上面介绍的这种根据索引访问元素的方法,array还有自己更为优秀的方法!

1使用布尔数组

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

>>> b=a>3

>>> b

array([False, False, False, False, True, True, True])

>>> a[b]

array([4, 5, 6])

值得注意的是,这种方法只适用于数组,list没有资格。如上例所示,布尔索引最终返回的是下标为True的数据。

2列表索引

>>> a=np.array(['a','b','c','d','e'])

>>> a

array(['a', 'b', 'c', 'd', 'e'], dtype='>> b=[0,1]

>>> a[b]

array(['a', 'b'], dtype='>> 

列表索引适用于数组和list对象。

以上两个「花式索引」他们都不和原来的数据共享内存。

 

今天这篇笔记主要是想要总结一下array和list的区别。

一个python元素其实是一个指向这个包含所有python object信息的内存的位置指针。

list:一个指向一系列指针块的指针,其中每个指针都指向一个完整的python object-对象,例如integer。每一个list 元素是一个包括数据和信息类型的完整结构。所以列表可以填充任意类型的数据。

numpy.array:底层是C语言。有步长strides,dimensions,data三属性。他的元素类型固定,缺乏灵活,但是更方便进行存储和处理数据。

参考链接

[1]https://blog.csdn.net/wyl1813240346/article/details/79806207

[2]https://blog.csdn.net/liyaohhh/article/details/51055147#reply

[3]https://docs.scipy.org/doc/numpy-dev/user/quickstart.html

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(python)