构建数组¶
日期 | 2018-03-26(最后修改),2006-02-07(创建) |
---|
本节简要介绍数组对象,包括其声明和在 SciPy 中的使用。有关 Numpy 数组函数的全面示例列表,请参阅 Numpy 示例列表及文档
基础¶
标准 Python 语言中尚未定义数值数组。要将数组对象及其方法加载到命名空间中,必须导入 Numpy 包
from numpy import *
可以使用 array 函数从通常的 Python 列表和元组创建数组。例如,
a = array([1,2,3])
返回一个一维整数数组。数组实例附带有一组大量的方法和属性。例如,是数组的维度。在本例中,它将是 。
数组对象与 Python 的序列对象之间的一个主要区别是数学运算符的定义。两个列表的加法会将这些列表连接起来,而两个数组的加法会逐元素地添加数组。例如,
b = array((10,11,12))
a + b
减法、乘法和除法类似地定义。
初学者常犯的一个错误是数组的类型定义。除非另有说明,否则 array 构造函数将使用其参数的类型。由于 是从整数列表创建的,因此它被定义为一个整数数组,更准确地说,是
a.dtype
因此,像除法这样的数学运算在 Python 中将按预期进行,即返回整数答案。
a/3
为了获得预期的答案,一种解决方案是通过除以一个实数来强制将整数转换为实数。更谨慎的方法是在初始化时定义类型。
a = array([1,2,3], dtype=float)
另一种转换方法是使用 NumPy 的内置转换函数 astype
和 cast
。这些函数允许您更改正在处理的数据类型。
a = array([1,2,3], dtype=int)
b = a.astype('float')
使用方括号表示法访问数组元素,其中 是从 0 开始的整数索引。可以使用 start:stop:step
格式的通用索引访问子数组。a[start:stop:step]
将返回对数组 a
的子数组的引用,该子数组从索引 start
处的元素开始(包括),一直到索引 stop
处的元素(不包括),步长为 step。例如:
data = array([0.5, 1.2, 2.2, 3.4, 3.5, 3.4, 3.4, 3.4], float)
t = arange(len(data), dtype='float') * 2*pi/(len(data)-1)
t[:] # get all t-values
t[2:4] # get sub-array with the elements at the indexes 2,3
t[slice(2,4)] # the same using slice
t[0:6:2] # every even-indexed value up to but excluding 6
此外,还可以使用布尔数组访问数组元素。布尔数组的元素索引设置为 True,表示要访问的元素。
i = array(len(t)*[False], bool) # create an bool-array for indexing
i[2] = True; i[4] = True; i[6] = True # we want elements with indexes 2,4 and 6
t[i]
我们可以使用这种语法来构建更复杂的结构。考虑之前定义的 data[:]
和 t[:]
数组。假设我们想要获取四个 (t[i]/data[i]
) 对,其中四个 t[i]
值最接近点 p=1.8
。我们可以按照以下步骤进行:
p=1.8 # set our point
abs(t-p) # how much do the t[:]-values differ from p?
dt_m = sort(abs(t-p))[3] # how large is the 4-th largest absolute distance between the
# t[:]-values and p
abs(t-p) <= dt_m # where are the four elements of t[:]closest to p ?
y_p = data[abs(t-p) <= dt_m] # construct the sub-arrays; (1) get the 4 t[:]-values
t_p = t[abs(t-p) <= dt_m] # (2) get the data t[:]-values corresponding to the 4 t[:] values
y_p
t_p
需要注意的是,切片返回对数据的引用。因此,返回的子数组中的更改会导致原始数组中的更改,反之亦然。如果只想复制值,可以使用矩阵对象的 copy()
方法。例如:
# first lets define a 2-d matrix
A = array([[0, 1, 2, 3], # initialize 2-d array
[4, 5, 6, 7],
[8, 9, 10, 11],
[12, 13, 14, 15]])
A
b=A[1:3,0:2] # let's get a sub-matrix containing the cross-section of
# rows 1,2 and columns 0,1
# !attention! this assigns to b a reference to the
# sub-matrix of A
b
c=A[1:3,0:2].copy() # copy the entries
c
A[1:3,0:2] = 42 # we can also assign by slicing (this also changes shallow copies)
b # b also affected (only a reference to sub matrix)
c # still the same (deep copy)
矩阵点积¶
以下示例创建两个矩阵:a
和 b
,并计算点积 axb
(换句话说,标准矩阵乘积)。
a = array([[1,2], [2,3]])
b = array([[7,1], [0,1]])
dot(a, b)
从 Python 3.5 开始,可以使用 @
运算符进行矩阵乘法。
a @ b
自动数组创建¶
SciPy(通过 Numpy)提供了多种方法来自动创建数组。例如,要创建等间距数字的向量,可以使用 linspace 函数。这在计算函数在某个域上的结果时很有用。例如,要计算函数在一个周期上的值,我们可以定义一个从 0 到 2π(π)的向量,并计算该向量中所有值的函数值。
x = linspace(0, 2*pi, 100)
y = sin(x)
可以使用类及其一些对象创建方法在 N 维网格上执行相同的操作。例如,
x, y = mgrid[0:10:.1, 0:10:.2]
返回两个矩阵 x 和 y,其元素分别以 0.1 和 0.2 的增量从 0 到 10(不包括 10)。这些矩阵可用于计算由这些网格定义的点 (x_i, y_i) 上的函数值。
z = (x+y)**2
ogrid 对象具有完全相同的行为,但它不将 N 维矩阵存储到内存中,而是只存储定义它的 1 维向量。对于大型矩阵,这可以节省大量的内存空间。
其他用于创建矩阵的有用函数是 和 ,它们初始化全为零和一的数组。请注意,这些数组默认情况下将是浮点数组。这可能会导致不了解的人产生奇怪的行为。例如,让我们初始化一个全为零的矩阵,然后逐元素地放置值。
mz = zeros((2, 2), dtype=int)
mz[0, 0] = .5**2
mz[1, 1] = 1.6**2
在这个例子中,我们试图将浮点数存储到一个整数数组中。因此,这些数字将被重新转换为整数,所以如果我们打印矩阵,我们会得到
mz
要创建实数数组,只需在调用函数时明确指定类型即可。
mz = zeros((2, 2), dtype=float)
重复数组段 ¶
ndarray.repeat() 方法返回一个新的数组,其维度从旧数组中重复。
a = array([[0, 1],
... [2, 3]])
a.repeat(2, axis=0) # repeats each row twice in succession
a.repeat(3, axis=1) # repeats each column 3 times in succession
a.repeat(2, axis=None) # flattens (ravels), then repeats each element twice
这些可以组合起来做一些有用的事情,比如放大存储在 2D 数组中的图像数据。
def enlarge(a, x=2, y=None):
"""Enlarges 2D image array a using simple pixel repetition in both dimensions.
Enlarges by factor x horizontally and factor y vertically.
If y is left as None, uses factor x for both dimensions."""
a = asarray(a)
assert a.ndim == 2
if y == None:
y = x
for factor in (x, y):
assert factor.__class__ == int
assert factor > 0
return a.repeat(y, axis=0).repeat(x, axis=1)
enlarge(a, x=2, y=2)
章节作者:DavidHuard,Unknown[26],Unknown[27],GaelVaroquaux,Unknown[28],BillBaxter,NilsWagner,MartinSpacek,Unknown[29],Unknown[5],Unknown[30],Unknown[31],Unknown[32],arjen,Joseph C. Slater