预备阅读:Python之numpy数组学习(一)Python之numpy数组学习(二)Python之numpy数组学习(三)
为获得良好代码体验,建议查看原文。
前言
前面我们学习了numpy库的简单应用和数组的处理,今天来学习下数组的视图和索引。
创建数组的视图和拷贝
在学习ravel()函数的时候,我看到了视图的概念,这让我很惊讶,但是注意,这里的视图和数据库中的视图不是一样的。在numpy中,视图不是只读的。关键在于,当前处理的是共享的数组视图,还是数组数据的副本。举例来说,可以取数组的一部分来生成视图,这意味着,如果先将数组的某部分赋值给一个变量,然后修改原数组中相应位置的数据,那么这个变量的值也会随之变化。
这里,我们通过动物面部照片(face)照片来创建数组,然后创建视图,随后修改。这里的动物面部照片的数组是从Scipy函数获得。
看一下代码和效果图如下:
#-*- coding:utf-8 -*-
import scipy.misc
import matplotlib.pyplot as plt
#创建图片数组
face = scipy.misc.face()
print (face.shape)
#副本
acopy = face.copy()
#创建视图
aview = face.view()
# 展示照片数组
plt.subplot(221)
plt.imshow(face)
#展示照片数据副本
plt.subplot(222)
plt.imshow(acopy)
#展示视图
plt.subplot(223)
plt.imshow(aview)
# 展示改变后的
aview.flat = 0
plt.subplot(224)
plt.imshow(aview)
plt.show()
可以看到,只有一副图片可以看到该动物图片,如上图所示。
同样可以看到,程序最后修改了视图,同时改变了原来的照片数组,这导致3副图片全部变黑。而复制的数组没有变化。所以,要记住:numpy中,视图不是只读的。
Numpy的索引
1、花式索引
花式索引是一种传统的索引方法,它不使用整数或者切片。这里,我们将利用花式索引来把动物图片(face)对角线上的值全部置0,相当于沿着两条交叉的对角线画两条黑线。
看一下完整代码和效果。
#-*- coding:utf-8 -*-
import scipy.misc
import matplotlib.pyplot as plt
# 加载图片数组
face = scipy.misc.face()
'''
这里说明一下,默认是正方形的图片,如果不是,则需要xmax和ymax的值一样大小。(PS.Python3.6中scipy的图片规格变成了768*1024)
'''
xmax = face.shape[0]
ymax = face.shape[0]
#ymax = face.shape[1]报错,
#IndexError: shape mismatch: indexingarrays could not be broadcast together with shapes (768,) (1024,)
# 设置对角线的值为0
# x 0-xmax
# y 0-ymax
face[range(xmax), range(ymax)] = 0
# 设置另一条对角线的值为0
# x xmax-0
# y 0-ymax
face[range(xmax-1,-1,-1), range(ymax)] = 0
# 展示效果
plt.imshow(face)
plt.show()
2、基于位置列表的索引方法
下面利用ix_()函数将动物图片的像素完全打乱。这个函数可以根据多个序列生成一个网格,它需要一个一维序列作为参数,并返回一个由numpy数组构成的元组。
利用位置列表索引numpy数组的过程如下:
① 打乱数组的索引。用numpy.random子程序包中的shuffle()函数把数组中的元素按随机的索引号重新排列,使数组产生相应的变化。
② 使用代码画出打乱后的索引。
③ 照片的像素被完全打乱后,展示效果。
代码和效果如下图所示:
#-*- coding:utf-8 -*-
import scipy.misc
import matplotlib.pyplot as plt
import numpy as np
# 加载图片数组
face = scipy.misc.face()
xmax = face.shape[0]
ymax = face.shape[1]
#打乱数组的索引
def shuffle_indices(size):
arr = np.arange(size)
np.random.shuffle(arr)
return arr
xindices = shuffle_indices(xmax)
np.testing.assert_equal(len(xindices), xmax)
yindices = shuffle_indices(ymax)
np.testing.assert_equal(len(yindices), ymax)
# 重画打乱后的索引
plt.imshow(face[np.ix_(xindices, yindices)])
plt.show()
3、用布尔型变量索引numpy数组
布尔型索引是指根据布尔型数组来索引元素的方法,属于花式索引系列。因为布尔型索引是花式索引的一个分类,所以它们的使用方法基本相同。
下面看代码和效果展示。
#-*- coding:utf-8 -*-
import scipy.misc
import matplotlib.pyplot as plt
import numpy as np
# 加载图片数组
face = scipy.misc.face()
#在对角线上画点
def get_indices(size):
arr = np.arange(size)
return arr % 4 == 0
# 仅绘画出选定的点
face1 = face.copy()
xindices = get_indices(face.shape[0])
yindices = get_indices(face.shape[0])#因为图片大小不是正方形,这里截取正方形图片
face1[xindices, yindices] = 0
plt.subplot(211)
plt.imshow(face1)
face2 = face.copy()
#选取数组值介于最大值的1/4到3/4的元素,将其置0
face2[(face > face.max()/4) & (face < 3 * face.max()/4)] = 0
plt.subplot(212)
plt.imshow(face2)
#展示效果
plt.show()
小结
今天学习一下Python中numpy数组的视图和索引。希望通过上面的操作能帮助大家。如果你有什么好的意见,建议,或者有不同的看法,我都希望你留言和我们进行交流、讨论。
欢迎关注微信公众号,访问更多精彩:AiryData。
如需转载,请联系授权,谢谢合作。