import numpy as np
a = np.array([0, 1, 2, 3])
a
例如,数组包含:
...
为什么有用:提供了高速数值操作的节省内存的容器。
L = range(1000)
%timeit [i**2 for i in L]
a = np.arange(1000)
%timeit a**2
np.array?
String Form:<built-in function array>
Docstring:
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0, ...
查找东西:
np.lookfor('create array')
import numpy as np
a = np.array([0, 1, 2, 3])
a
a.ndim
a.shape
len(a)
b = np.array([[0, 1, 2], [3, 4, 5]]) # 2 x 3 数组
b
b.ndim
b.shape
len(b) # 返回一个纬度的大小
c = np.array([[[1], [2]], [[3], [4]]])
c
c.shape
a = np.arange(10) # 0 .. n-1 (!)
a
b = np.arange(1, 9, 2) # 开始,结束(不包含),步长
b
c = np.linspace(0, 1, 6) # 起点、终点、数据点
c
d = np.linspace(0, 1, 5, endpoint=False)
d
a = np.ones((3, 3)) # 提示: (3, 3) 是元组
a
b = np.zeros((2, 2))
b
c = np.eye(3)
c
d = np.diag(np.array([1, 2, 3, 4]))
d
np.random
: 随机数 (Mersenne Twister PRNG) :a = np.random.rand(4) # [0, 1] 的均匀分布
a
b = np.random.randn(4) # 高斯
b
np.random.seed(1234) # 设置随机种子
np.random.rand?
练习:用函数创建数组
arange
、linspace
、ones
、zeros
、eye
和diag
。np.empty
。它能做什么?什么时候会比较有用?你可能已经发现,在一些情况下,数组元素显示带有点(即 2. VS 2)。这是因为所使用的数据类型不同:
a = np.array([1, 2, 3])
a.dtype
b = np.array([1., 2., 3.])
b
不同的数据类型可以更紧凑的在内存中存储数据,但是大多数时候我们都只是操作浮点数据。注意,在上面的例子中,Numpy自动从输入中识别了数据类型。
你可以明确的指定想要的类型:
c = np.array([1, 2, 3], dtype=float)
c.dtype
默认数据类型是浮点:
a = np.ones((3, 3))
a.dtype
其他类型:
复数:
d = np.array([1+2j, 3+4j, 5+6*1j])
d.dtype
布尔:
e = np.array([True, False, False, True])
e.dtype
字符:
f = np.array(['Bonjour', 'Hello', 'Hallo',])
f.dtype # <--- 包含最多7个字母的字符
更多:
现在我们有了第一个数组,我们将要进行可视化。
从pylab模式启动IPython。
ipython --pylab
或notebook:
ipython notebook --pylab=inline
或者如果IPython已经启动,那么:
%pylab
或者从Notebook中:
%pylab inline
inline
对notebook来说很重要,以便绘制的图片在notebook中显示而不是在新窗口显示。
Matplotlib是2D制图包。我们可以像下面这样导入它的方法:
import matplotlib.pyplot as plt #整洁形式
然后使用(注你需要显式的使用 show
):
plt.plot(x, y) # 线图
plt.show() # <-- 显示图表(使用pylab的话不需要)
或者,如果你使用 pylab
:
plt.plot(x, y) # 线图
在脚本中推荐使用 import matplotlib.pyplot as plt
。 而交互的探索性工作中用 pylab
。
x = np.linspace(0, 3, 20)
y = np.linspace(0, 9, 20)
plt.plot(x, y) # 线图
plt.plot(x, y, 'o') # 点图
image = np.random.rand(30, 30)
plt.imshow(image, cmap=plt.cm.hot)
plt.colorbar()
更多请见matplotlib部分
练习:简单可视化
画出简单的数组:cosine作为时间的一个函数以及2D矩阵。
在2D矩阵上试试使用 gray
colormap。
数组的项目可以用与其他Python序列(比如:列表)一样的方式访问和赋值:
a = np.arange(10)
a
a[0], a[2], a[-1]
警告:索引从0开始与其他的Python序列(以及C/C++)一样。相反,在Fortran或者Matlab索引从1开始。
使用常用的Python风格来反转一个序列也是支持的:
a[::-1]
对于多维数组,索引是整数的元组:
a = np.diag(np.arange(3))
a
a[1, 1]
a[2, 1] = 10 # 第三行,第二列
a
a[1]
注:
a
,a[0]被解释为提取在指定维度的所有元素切片:数组与其他Python序列也可以被切片:
a = np.arange(10)
a
a[2:9:3] # [开始:结束:步长]
注意最后一个索引是不包含的!:
a[:4]
切片的三个元素都不是必选:默认情况下,起点是0,结束是最后一个,步长是1:
a[1:3]
a[::2]
a[3:]
Numpy索引和切片的一个小说明...
赋值和切片可以结合在一起:
a = np.arange(10)
a[5:] = 10
a
b = np.arange(5)
a[5:] = b[::-1]
a
练习:索引与切片
np.arange(6) + np.arange(0, 51, 10)[:, np.newaxis]
练习:数组创建
创建下列的数组(用正确的数据类型):
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 2],
[1, 6, 1, 1]]
[[0., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[0., 3., 0., 0., 0.],
[0., 0., 4., 0., 0.],
[0., 0., 0., 5., 0.],
[0., 0., 0., 0., 6.]]
参考标准:每个数组
提示:每个数组元素可以像列表一样访问,即a[1] 或 a[1, 2]。
提示:看一下 diag
的文档字符串。
练习:创建平铺数组
看一下 np.tile
的文档,是用这个函数创建这个数组:
[[4, 3, 4, 3, 4, 3],
[2, 1, 2, 1, 2, 1],
[4, 3, 4, 3, 4, 3],
[2, 1, 2, 1, 2, 1]]
切片操作创建原数组的一个视图,这只是访问数组数据一种方式。因此,原始的数组并不是在内存中复制。你可以用 np.may_share_memory()
来确认两个数组是否共享相同的内存块。但是请注意,这种方式使用启发式,可能产生漏报。
当修改视图时,原始数据也被修改:
a = np.arange(10)
a
b = a[::2]
b
np.may_share_memory(a, b)
b[0] = 12
b
a # (!)
a = np.arange(10)
c = a[::2].copy() # 强制复制
c[0] = 12
a
np.may_share_memory(a, c)
乍看之下这种行为可能有些奇怪,但是这样做节省了内存和时间。
实例:素数筛选
用筛选法计算0-99之间的素数
_prime
形状是 (100,) 的布尔数组,在初始将值都设为True:is_prime = np.ones((100,), dtype=bool)
is_prime[:2] = 0
对于从2开始的整数 j
,化掉它的倍数:
N_max = int(np.sqrt(len(is_prime)))
for j in range(2, N_max):
is_prime[2*j::j] = False
help(np.nonzero)
,然后打印素数prime_sieve.py
的脚本文件j
np.random.seed(3)
a = np.random.random_integers(0, 20, 15)
a
(a % 3 == 0)
mask = (a % 3 == 0)
extract_from_a = a[mask] # 或, a[a%3==0]
extract_from_a # 用面具抽取一个子数组
赋值给子数组时,用面具索引非常有用:
a[a % 3 == 0] = -1
a
a = np.arange(0, 100, 10)
a
索引可以用整型数组完成,其中相同的索引重复了几次:
a[[2, 3, 2, 4, 2]] # 注:[2, 3, 2, 4, 2] 是Python列表
用这种类型的索引可以分配新值:
a[[9, 7]] = -100
a
当一个新数组用整型数组索引创建时,新数组有相同的形状,而不是整数数组:
a = np.arange(10)
idx = np.array([[3, 4], [9, 7]])
idx.shape
a[idx]
下图展示了多种象征索引的应用
练习:象征索引
a = np.array([1, 2, 3, 4])
a + 1
2**a
所有运算是在元素级别上操作:
b = np.ones(4) + 1
a - b
a * b
j = np.arange(5)
2**(j + 1) - j
这些操作当然也比你用纯Python实现好快得多:
a = np.arange(10000)
%timeit a + 1
l = range(10000)
%timeit [i+1 for i in l]
注意:数组相乘不是矩阵相乘:
c = np.ones((3, 3))
c * c # 不是矩阵相乘!
注:矩阵相乘:
c.dot(c)
练习:元素级别的操作
%timeit
比一下他们与纯Python对等物的时间[2**0, 2**1, 2**2, 2**3, 2**4]
a_j = 2^(3*j) - j
对比:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
a == b
a > b
数组级别的对比:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
c = np.array([1, 2, 3, 4])
np.array_equal(a, b)
np.array_equal(a, c)
逻辑操作:
a = np.array([1, 1, 0, 0], dtype=bool)
b = np.array([1, 0, 1, 0], dtype=bool)
np.logical_or(a, b)
np.logical_and(a, b)
a = np.arange(5)
np.sin(a)
np.log(a)
np.exp(a)
形状不匹配
a = np.arange(4)
a + np.array([1, 2])
广播?我们将在稍后讨论。
变换
a = np.triu(np.ones((3, 3)), 1) # 看一下 help(np.triu)
a
a.T
警告:变换是视图
因此,下列的代码是错误的,将导致矩阵不对称:
a += a.T
x = np.array([1, 2, 3, 4])
np.sum(x)
x.sum()
行求和和列求和:
x = np.array([[1, 1], [2, 2]])
x
x.sum(axis=0) # 列 (第一纬度)
x[:, 0].sum(), x[:, 1].sum()
x.sum(axis=1) # 行 (第二纬度)
x[0, :].sum(), x[1, :].sum()
高维的处理,思路相同:
x = np.random.rand(2, 2, 2)
x.sum(axis=2)[0, 1]
x[0, 1, :].sum()
axis=
)极值
x = np.array([1, 3, 2])
x.min()
x.max()
x.argmin() # 最小值的索引
x.argmax() # 最大值的索引
逻辑运算:
np.all([True, True, False])
np.any([True, True, False])
注:可以被应用数组对比:
a = np.zeros((100, 100))
np.any(a != 0)
np.all(a == a)
a = np.array([1, 2, 3, 2])
b = np.array([2, 2, 3, 2])
c = np.array([6, 4, 4, 5])
((a <= b) & (b <= c)).all()
统计:
x = np.array([1, 2, 3, 1])
y = np.array([[1, 2, 3], [5, 6, 1]])
x.mean()
np.median(x)
np.median(y, axis=-1) # 最后的坐标轴
x.std() # 全体总体的标准差。
... 以及其他更多(随着你成长最好学习一下)。
练习:简化
sum
,你会期望看到哪些其他的函数?sum
和 cumsum
有什么区别?实例: 数据统计
populations.txt中的数据描述了过去20年加拿大北部野兔和猞猁的数量(以及胡萝卜)。
你可以在编辑器或在IPython看一下数据(shell或者notebook都可以):
cat data/populations.txt
首先,将数据加载到Numpy数组:
data = np.loadtxt('data/populations.txt')
year, hares, lynxes, carrots = data.T # 技巧: 将列分配给变量
接下来作图:
from matplotlib import pyplot as plt
plt.axes([0.2, 0.1, 0.5, 0.8])
plt.plot(year, hares, year, lynxes, year, carrots)
plt.legend(('Hare', 'Lynx', 'Carrot'), loc=(1.05, 0.5))
随时间变化的数量的平均数:
populations = data[:, 1:]
populations.mean(axis=0)
样本的标准差:
populations.std(axis=0)
每一年哪个物种有最高的数量?:
np.argmax(populations, axis=1)
实例:随机游走算法扩散
让我们考虑一下简单的1维随机游走过程:在每个时间点,行走者以相等的可能性跳到左边或右边。我们感兴趣的是找到随机游走者在 t
次左跳或右跳后距离原点的典型距离?我们将模拟许多”行走者“来找到这个规律,并且我们将采用数组计算技巧来计算:我们将创建一个2D数组记录事实,一个方向是经历(每个行走者有一个经历),一个纬度是时间:
n_stories = 1000 # 行走者的数
t_max = 200 # 我们跟踪行走者的时间
我们随机选择步长1或-1去行走:
t = np.arange(t_max)
steps = 2 * np.random.random_integers(0, 1, (n_stories, t_max)) - 1
np.unique(steps) # 验证: 所有步长是1或-1
我们通过汇总随着时间的步骤来构建游走
positions = np.cumsum(steps, axis=1) # axis = 1: 纬度是时间
sq_distance = positions**2
获得经历轴的平均数:
mean_sq_distance = np.mean(sq_distance, axis=0)
画出结果:
plt.figure(figsize=(4, 3))
plt.plot(t, np.sqrt(mean_sq_distance), 'g.', t, np.sqrt(t), 'y-')
plt.xlabel(r"$t$")
plt.ylabel(r"$\sqrt{\langle (\delta x)^2 \rangle}$")
我们找到了物理学上一个著名的结果:均方差记录是时间的平方根!
下图给出了一个广播的例子:
让我们验证一下:
a = np.tile(np.arange(0, 40, 10), (3, 1)).T
a
b = np.array([0, 1, 2])
a + b
在不知道广播的时候已经使用过它!:
a = np.ones((4, 5))
a[0] = 2 # 我们将一个数组的纬度0分配给另一个数组的纬度1
a
a = np.ones((4, 5))
print a[0]
a[0] = 2 # 我们将一个数组的纬度0分配给另一个数组的纬度
a
一个有用的技巧:
a = np.arange(0, 40, 10)
a.shape
a = a[:, np.newaxis] # 添加一个新的轴 -> 2D 数组
a.shape
a
a + b
广播看起来很神奇,但是,当我们要解决的问题是输出数据比输入数据有更多纬度的数组时,使用它是非常自然的。
实例:广播
让我们创建一个66号公路上城市之间距离(用公里计算)的数组:芝加哥、斯普林菲尔德、圣路易斯、塔尔萨、俄克拉何马市、阿马里洛、圣塔菲、阿尔布开克、Flagstaff、洛杉矶。
mileposts = np.array([0, 198, 303, 736, 871, 1175, 1475, 1544, 1913, 2448])
distance_array = np.abs(mileposts - mileposts[:, np.newaxis])
distance_array
许多基于网格或者基于网络的问题都需要使用广播。例如,如果要计算10X10网格中每个点到原点的数据,可以这样:
x, y = np.arange(5), np.arange(5)[:, np.newaxis]
distance = np.sqrt(x ** 2 + y ** 2)
distance
或者用颜色:
plt.pcolor(distance)
plt.colorbar()
评论 : numpy.ogrid
函数允许直接创建上一个例子中两个重要纬度向量X和Y:
x, y = np.ogrid[0:5, 0:5]
x, y
x.shape, y.shape
distance = np.sqrt(x ** 2 + y ** 2)
因此, np.ogrid
就非常有用,只要我们是要处理网格计算。另一方面, 在一些无法(或者不想)从广播中收益的情况下,np.mgrid
直接提供了由索引构成的矩阵:
x, y = np.mgrid[0:4, 0:4]
x
y
a = np.array([[1, 2, 3], [4, 5, 6]])
a.ravel()
a.T
a.T.ravel()
a.shape
b = a.ravel()
b = b.reshape((2, 3))
b
或者:
a.reshape((2, -1)) # 不确定的值(-1)将被推导
警告: ndarray.reshape
可以返回一个视图(参见 help(np.reshape)
), 也可以可以返回副本
b[0, 0] = 99
a
当心:重排也可以返回一个副本!:
a = np.zeros((3, 2))
b = a.T.reshape(3*2)
b[0] = 9
a
z = np.array([1, 2, 3])
z
z[:, np.newaxis]
z[np.newaxis, :]
a = np.arange(4*3*2).reshape(4, 3, 2)
a.shape
a[0, 2, 1]
b = a.transpose(1, 2, 0)
b.shape
b[2, 1, 0]
也是创建了一个视图:
b[2, 1, 0] = -1
a[0, 2, 1]
可以用 ndarray.resize
改变数组的大小:
a = np.arange(4)
a.resize((8,))
a
但是,它不能在其他地方引用:
b = a
a.resize((4,))
练习:形状操作
reshape
的文档字符串,特别要注意其中关于副本和视图的内容。flatten
来替换 ravel
。有什么区别? (提示: 试一下哪个返回视图哪个返回副本)transpose
来进行纬度变换。按一个轴排序:
a = np.array([[4, 3, 5], [1, 2, 1]])
b = np.sort(a, axis=1)
b
注:每行分别排序!
原地排序:
a.sort(axis=1)
a
象征索引排序:
a = np.array([4, 3, 1, 2])
j = np.argsort(a)
j
a[j]
找到最大值和最小值:
a = np.array([4, 3, 1, 2])
j_max = np.argmax(a)
j_min = np.argmin(a)
j_max, j_min
练习:排序
all
或者 array_equal
来检查一下结果。np.random.shuffle
,一种更快创建可排序输入的方式。ravel
、sort
和 reshape
。sort
的 axis
关键字,重写一下这个练习。入门你需要了解什么?
array
、arange
、ones
、zeros
。array.shape
数组的形状,然后使用切片来获得数组的不同视图:array[::2]
等。用 reshape
改变数组形状或者用 ravel
扁平化。a[a < 0] = 0
array.max()
、array.mean()
)。不需要记住所有东西,但是应该有条件反射去搜索文档 (线上文档, help()
, lookfor()
)!!快读阅读
如果你想要快速通过科学讲座笔记来学习生态系统,你可以直接跳到下一章:Matplotlib: 作图(暂缺)。
本章剩下的内容对于学习介绍部分不是必须的。但是,记得回来完成本章并且完成更多的练习。
“更大”的类型在混合类型操作中胜出:
np.array([1, 2, 3]) + 1.5
赋值不会改变类型!
a = np.array([1, 2, 3])
a.dtype
a[0] = 1.9 # <-- 浮点被截取为整数
a
强制投射:
a = np.array([1.7, 1.2, 1.6])
b = a.astype(int) # <-- 截取整数
b
四舍五入:
a = np.array([1.2, 1.5, 1.6, 2.5, 3.5, 4.5])
b = np.around(a)
b # 仍然是浮点
c = np.around(a).astype(int)
c
整数 (带有符号):
类型 | 字节数 |
---|---|
int8 | 8 bits |
int16 | 16 bits |
int32 | 32 bits (与32位平台的int相同) |
int64 | 64 bits (与64位平台的int相同) |
np.array([1], dtype=int).dtype
np.iinfo(np.int32).max, 2**31 - 1
np.iinfo(np.int64).max, 2**63 - 1
无符号整数:
类型 | 字节数 |
---|---|
uint8 | 8 bits |
uint16 | 16 bits |
uint32 | 32 bits |
uint64 | 64 bits |
np.iinfo(np.uint32).max, 2**32 - 1
np.iinfo(np.uint64).max, 2**64 - 1
浮点数据:
类型 | 字节数 |
---|---|
float16 | 16 bits |
float32 | 32 bits |
float64 | 64 bits (与浮点相同) |
float96 | 96 bits, 平台依赖 (与 np.longdouble 相同) |
float128 | 128 bits, 平台依赖 (与 np.longdouble 相同) |
np.finfo(np.float32).eps
np.finfo(np.float64).eps
np.float32(1e-8) + np.float32(1) == 1
np.float64(1e-8) + np.float64(1) == 1
浮点复数:
类型 | 字节数 |
---|---|
complex64 | 两个 32-bit 浮点 |
complex128 | 两个 64-bit 浮点 |
complex192 | 两个 96-bit 浮点, 平台依赖 |
complex256 | 两个 128-bit 浮点, 平台依赖 |
更小的数据类型
如果你不知道需要特殊数据类型,那你可能就不需要。
比较使用 float32
代替 float64
:
a = np.zeros((1e6,), dtype=np.float64)
b = np.zeros((1e6,), dtype=np.float32)
%timeit a*a
%timeit b*b
名称 | 类型 |
---|---|
sensor_code | (4个字母的字符) |
position | (浮点) |
value | (浮点) |
samples = np.zeros((6,), dtype=[('sensor_code', 'S4'),('position', float), ('value', float)])
samples.ndim
samples.shape
samples.dtype.names
samples[:] = [('ALFA', 1, 0.37), ('BETA', 1, 0.11), ('TAU', 1, 0.13),('ALFA', 1.5, 0.37), ('ALFA', 3, 0.11),
('TAU', 1.2, 0.13)]
samples
用字段名称索引也可以访问字段:
samples['sensor_code']
samples['value']
samples[0]
samples[0]['sensor_code'] = 'TAU'
samples[0]
一次多个字段:
samples[['position', 'value']]
和普通情况一样,象征索引也有效:
samples[samples['sensor_code'] == 'ALFA']
x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
x
y = np.ma.array([1, 2, 3, 4], mask=[0, 1, 1, 1])
x + y
np.ma.sqrt([1, -1, 2, -2])
注:有许多其他数组的兄弟姐妹
尽管这脱离了Numpy这章的主题,让我们花点时间回忆一下编写代码的最佳实践,从长远角度这绝对是值得的:
最佳实践
风格:逗号后及=周围有空格等。
在Python代码风格指南及文档字符串惯例页面中给出了相当数据量如何书写“漂亮代码”的规则(并且,最重要的是,与其他人使用相同的惯例!)。
1.3.4.1. 多项式
Numpy也包含不同基的多项式:
例如,$3x^2 + 2x - 1$:
p = np.poly1d([3, 2, -1])
p(0)
p.roots
p.order
x = np.linspace(0, 1, 20)
y = np.cos(x) + 0.3*np.random.rand(20)
p = np.poly1d(np.polyfit(x, y, 3))
t = np.linspace(0, 1, 200)
plt.plot(x, y, 'o', t, p(t), '-')
更多内容见http://docs.scipy.org/doc/numpy/reference/routines.polynomials.poly1d.html。
Numpy也有更复杂的多项式接口,支持比如切比雪夫基。
$3x^2 + 2x - 1$:
p = np.polynomial.Polynomial([-1, 2, 3]) # 系数的顺序不同!
p(0)
p.roots()
p.degree() # 在普通的多项式中通常不暴露'order'
在切尔雪夫基中使用多项式的例子,多项式的范围在[-1,1]:
x = np.linspace(-1, 1, 2000)
y = np.cos(x) + 0.3*np.random.rand(2000)
p = np.polynomial.Chebyshev.fit(x, y, 90)
t = np.linspace(-1, 1, 200)
plt.plot(x, y, 'r.')
plt.plot(t, p(t), 'k-', lw=3)
切尔雪夫多项式在插入方面有很多优势。
例子: populations.txt:
# year hare lynx carrot
1900 30e3 4e3 48300
1901 47.2e3 6.1e3 48200
1902 70.2e3 9.8e3 41500
1903 77.4e3 35.2e3 38200
data = np.loadtxt('data/populations.txt')
data
np.savetxt('pop2.txt', data)
data2 = np.loadtxt('pop2.txt')
注:如果你有一个复杂的文本文件,应该尝试:
np.genfromtxt
提示:用IPython在文件系统中航行
pwd # 显示当前目录
cd data
ls
使用Matplotlib:
img = plt.imread('data/elephant.png')
img.shape, img.dtype
plt.imshow(img)
plt.savefig('plot.png')
plt.imsave('red_elephant', img[:,:,0], cmap=plt.cm.gray)
这只保存了一个渠道(RGB):
plt.imshow(plt.imread('red_elephant.png'))
其他包:
from scipy.misc import imsave
imsave('tiny_elephant.png', img[::6,::6])
plt.imshow(plt.imread('tiny_elephant.png'), interpolation='nearest')
Numpy有自有的二进制格式,没有便携性但是I/O高效:
data = np.ones((3, 3))
np.save('pop.npy', data)
data3 = np.load('pop.npy')
scipy.io.netcdf_file
, netcdf4-python, ...scipy.io.loadmat
, scipy.io.savemat
scipy.io.mmread
, scipy.io.mmread
... 如果有人使用,那么就可能有一个对应的Python库。
练习:文本数据文件
写一个Python脚本从populations.txt加载数据,删除前五行和后五行。将这个小数据集存入 pop2.txt
。
Numpy内部
如果你对Numpy的内部感兴趣, 有一个关于Advanced Numpy的很好的讨论。
[[1, 6, 11],
[2, 7, 12],
[3, 8, 13],
[4, 9, 14],
[5, 10, 15]]
并且生成一个第二和第四行的新数组。
np.newaxis
): a = np.arange(25).reshape(5, 5)
b = np.array([1., 5, 10, 15, 20])
abs
和 argsort
找到每一行中最接近的列 j
。i
必须包含 j
中成分的对应行数)让我们从著名的Lena图(http://www.cs.cmu.edu/~chuck/lennapg/) 上开始,用Numpy数组做一些操作。Scipy在 scipy.lena
函数中提供了这个图的二维数组:
from scipy import misc
lena = misc.lena()
注:在旧版的scipy中,你会在 scipy.lena()
找到lena。
这是一些通过我们的操作可以获得图片:使用不同的颜色地图,裁剪图片,改变图片的一部分。
imshow
函数显示这个图片。import pylab as plt
lena = misc.lena()
plt.imshow(lena)
plt.imshow(lena, cmap=plt.cm.gray)