

作者 Airy
本文转自 AiryData,转载需授权
前面我们学习了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中,视图不是只读的。
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数组的视图和索引。希望通过上面的操作能帮助大家。如果你有什么好的意见,建议,或者有不同的看法,我都希望你留言和我们进行交流、讨论。

推荐阅读
我分析了 6.5W 字的歌词,看到了这样的周杰伦!
柯洁又输了,关于人工智能AlphaGo你需要知道些什么
男性人口过剩:亚洲性别比例失衡远比你想象中严重
【书单】18本数据科学家必读的R语言和Python相关书籍
如何像数据科学家一样思考
北京VS上海,哪座城市人口更多?
我是如何一不小心阻止了勒索病毒的全球蔓延
用python抓取摩拜单车API数据并做可视化分析(源码)
2017年大数据和数据科学的六大发展趋势
你每天要花多少时间在手机上?
初级数据科学家求职时的 3 大必备能力
不可错过的优质深度学习课程
职场 | 数据库面试常问的一些基本概念
听说你最擅长“拖”,你“拖”得过Excel吗?
数据科学优质课程推荐#2:统计入门课程篇
歌手外科和猴姑,大数据告诉你白百何出轨后谁最惨
想学习数据科学?我们整理了一份优质编程入门课程清单
数据科学家在美国仍然是最热门工作的3大原因
一个优秀数据分析师的准则

