Table of Contents
python列表和Numpy数组的区别
array的创建
元素访问
array的一维数组的访问方式
array的二维数组的访问方式
参考链接
1二者都可以用于处理多维数组。
Numpy中的ndarray对象用于处理多维数组,它作为一个快速而灵活的大数据容器。Python列表可以存储一维数组,通过列表的嵌套可以实现多维数组。
2存储效率和输入输出性能不同。
Numpy专门针对数组的操作和运算进行了设计,存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。
3元素数据类型。
通常,Numpy数组中的所有元素的类型都必须相同的,而Python列表中的元素类型是任意的,所以在通用性能方面Numpy数组不及Python列表,但在科学计算中,可以省掉很多循环语句,代码使用方面比Python列表简单的多。
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: 第三个参数决定了传递给函数的数据类型,默认为浮点型。
|
返回值 |
返回一个数组。
|
定义一个一维数组,
arr=np.array([0,1,2,3,4,5,6,7,8,9])
arr[5] |
访问第6个元素 #结果:5 |
arr[3:5] |
访问第4-5个元素 #结果: |
arr[:5] |
访问前5元素 #结果: |
arr[:-1] |
访问除了最后一个元素之外的元素 #结果: |
arr[:] |
访问全部 #结果 |
arr[2:4]=100 |
将3-4个元素置为100 #结果: |
arr[1:-1:2] |
访问从第一个到最后一个的元素,步长为2 #结果: |
arr[::-1] |
访问从第一个到最后一个的元素,步长为-1 #结果: |
其中,arr[a:b:n]表示按步长为n取从a到b的元素,当n为-1的时候,从右向左访问。
对于二维数组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