作者 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()