下面的文章中,将使用约定俗成的模块名 np
来表示 NumPy 库。
import numpy as np
1. 多维数组的创建
NumPy 提供了许多常用的函数来创建多维数组,先概览这些函数的名称及功能。
函数 | 说明 |
---|---|
array | 将输入数据转换为ndarray,可显式指定dtype。 |
asarray | 将输入转换为ndarray,如果输入本身为ndarray则不复制。 |
arange | 类似于range函数,返回的是ndarray而不是列表。 |
ones、ones_like | 根据指定的形状和dtype创建一个全1数组。ones_like以另一个数组为参数,并根据其形状和dtype创建一个全1数组。 |
zeros、zeros_like | 类似于ones和ones_like,只不过产生的是全0数组。 |
empty、empty_like | 创建新数组,只分配内存但不填充任何值。 |
eye、identity | 创建一个N*N单位矩阵(对角线为1,其余为0)。 |
array
语法:
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
示例:
>>> np.array([1, 2, 3])
array([1, 2, 3])
>>> np.array([1, 2, 3.0])
array([ 1., 2., 3.])
>>> np.array([[1, 2], [3, 4]])
array([[1, 2],
[3, 4]])
array 接受一切序列型对象,返回一个 NumPy 数组(ndarray)。如果我们没有指定元素的数据类型,那么 array 会自动为数组选择一个合适的数据类型,保存到 dtype 对象中。
2. dtype数据类型
类型 | 类型代码 | 说明 |
---|---|---|
int8 | i1、u1 | 8位整型 |
int16 | i2、u2 | 16位整型 |
int32 | i4、u4 | 32位整型 |
int64 | i8、u8 | 64位整型 |
float16 | f2 | 半精度浮点数 |
float32 | f4或f | 标准单精度浮点数。与C的float兼容。 |
float64 | f8或d | 标准双精度浮点数,与C的double和Python的float对象兼容。 |
float128 | f16或g | 扩展精度浮点数 |
complex64、complex128、complex256 | c32 | 复数 |
bool | ? | 布尔类型(True或False) |
object | O | Python对象类型 |
string | S | 定长字符串类型(每字符1字节)。 |
unicode | U | 定长unicode类型(字节数由平台决定)。跟字符串的定义方式一样。 |
创建 ndarray 对象时,可以使用类型代码来表示 dtype
arr_float = np.empty(10, dtype='f8')
ndarray 对象提供了 astype 方法来转换其 dtype
arr_int = np.array([1, 2, 3])
arr_float = arr_int.astype(np.float64)
3. 基本索引
与python内置的list类似,ndarray 对象也可以通过方括号来索引元素。例如:
arr = np.arrange(10)
arr[1:5]
arr[:3]
arr[-1]
不同之处在于,list的切片返回的是新对象,而 ndarray 切片后将返回原始数据的视图。也就是说,对于切片的任何修改都会反映在源数组上。例如:
>>> arr[3:8] = 1
array([0, 1, 2, 1, 1, 1, 1, 1, 8, 9])
要得到一个新的对象,可以通过 arr[3:8].copy()
来获得副本。
4. 高维度索引
Python 自身可以通过连续的方括号组合来索引多维数组,例如 arr[1][3]
。在 NumPy 中, ndarray 同样支持这种基本的索引方式。除此之外,ndarray 还支持另一种索引方式:
arr[1, 3]
通过逗号来分隔不同维度的索引,即获取二维数组 arr 中第一行第三列的元素。
基于此,我们可以在各维度中分别进行切片索引:
arr[2:5, :3]
这表示,获取由二维数组的2、3、4行第0、1、2列元素所构成的3x3二维数组。
5. 布尔型索引
布尔型索引,就是用一个形状与目标数组一模一样的布尔型数组,来索引目标数组对应位置的元素。布尔型数组元素的值只有True和False两种,True对应的目标数组元素将被选取,而False对应的元素将被忽略。
例如:
>>> arr = np.array(['a', 'b', 'c', 'd', 'e'])
>>> bools = np.array([True, False, True, False, True])
>>> arr[bools]
array(['a', 'c', 'e'])
多维数组与常量的比较运算会广播到每一个元素,也就是说,每个元素都会与该常量进行比较运算。我们可以利用这一点来生成布尔型索引数组:
>>> bools = arr > 'c'
>>> bools
array([False, False, False, True, True], dtype=bool)
>>> arr[bools]
array(['d', 'e'],
dtype='|S1')
常用的比较运算符有:==
, !=
, >
, <
, >=
, <=
还可以使用波浪号 ~
对布尔型数组取反,相当于对每个元素取反。
如果有多个条件,可以使用 &
和 |
运算符进行与运算和或运算。
6. 花式索引
花式索引(Fancy indexing)指的是利用整数数组进行索引。花式索引总是产生新的数组对象。
花式索引通过传入列表或数组,从而以特定顺序选取行子集。例如:
>>> arr = np.arange(16).reshape((4, 4))
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> arr[[3, 2, 0]]
array([[12, 13, 14, 15],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3]])
如果要让选定行子集的列,按指定顺序排列,可以写成:
>>> arr[[3, 2, 0]][:, [1, 2, 3, 0]]
array([[13, 14, 15, 12],
[ 9, 10, 11, 8],
[ 1, 2, 3, 0]])
上面代码中,前部分 arr[[3, 2, 0]]
实际上就是上一个示例的结果。我们就是在上一个结果的基础上进行索引,[:, [1, 2, 3, 0]]
,冒号表示选取所有行,而后面的列表指定了列的排列顺序。
7. 索引总结
普通高维度索引、布尔型索引与花式索引这三者之间其实有规律可循。
我们以二维数组 arr2d
为例。
7.1. 形式一
第一种索引的形式为 arr2d[i]
。由于 i 只是单个序列,只会筛选行子集,因此索引的结果包含所有列。
- 当 i 为单个数值时,结果是对应的行视图
- 当 i 为
a:b
的形式时,结果是第 a 行到第 b-1 行的 b-a 个行子集视图; - 当 i 为列表或数组时:
如果 i 为形状与 arr2d 相同的布尔型数组,则结果为 True 所对应的元素构成的新子集(布尔型索引);
如果元素为数值,结果是原数组对应行按列表或数组指定顺序排列形成的新子集(花式索引);
如果元素为布尔值,结果是 True 所对应的行构成的新子集。
7.2. 形式二
第二种索引的形式为 arr2d[i, j]
。由于 i,j 包含了每一个维度(此处为2),因此将对行和列进行筛选。
- 当 i、j 为数值时,结果是单个元素视图;
- 当 i、j 均为
a:b
的形式时,结果是 i 筛选出的行子集与 j 筛选出的列子集的公共部分视图; - 当 i、j 均为列表时:
如果元素为数值,结果等价于 zip(i, j) 中每个坐标所代表的元素构成的新子集;
如果元素为布尔值,结果等价于 zip(i, j) 中两个坐标值均为 True 的位置所对应的元素构成的新子集。
8. 转置和轴对换
在前面的示例中,我们使用了 reshape()
方法来重塑数组。
此外,多维数组还有 transpose 方法,用于指定轴的转置,返回源数据的视图。
以及 T 属性,返回转置(轴对换)后的数组,T 属性本身不可修改,但若赋值给别的变量,则会生成新的数组,可进行修改。
多维数组还有一个 swapaxes 方法,用于对换两个轴,返回源数据的视图。
9. 元素级数组函数
我们将用于多维数组中元素级运算的函数成为通用函数(ufunc),它们作用于每一个元素,接收一个或多个标量值,并产生一个或多个标量值。
9.1. 一元ufunc
函数 | 说明 |
---|---|
abs、fabs | 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs |
sqrt | 计算平方根。相当于 arr ** 0.5 |
square | 计算平方。相当于 arr ** 2 |
exp | 计算指数 e^x |
log、log10、log2、log1p | 底数为e、10、2的对数及log(1+x) |
sign | 计算正负号:1(正数)、0(零)、-1(负数) |
ceil | 向上取整 |
floor | 向下取整 |
rint | 四舍五入到最接近的整数,保留dtype |
modf | 将数组的小数和整数部分以两个独立数组的形式返回 |
isnan | 返回一个表示“哪些值是NaN(不是数字)”的布尔型数组 |
isfinite、isinf | 分别返回一个表示“哪些元素是有穷的”或“哪些元素是无穷的”的布尔型数组 |
cos、cosh、sin、sinh、tan、tanh | 普通型和双曲型三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函数 |
logical_not | 计算各元素 not x 的真值。相当于 ~arr |
9.2. 二元ufunc
函数 | 说明 |
---|---|
add | 元素相加 |
subtract | 第一个数组元素减去第二个数组元素 |
multiply | 元素相乘 |
divide、floor_divide | 除法或向下圆整除法(丢弃余数) |
power | 对第一个数组中的元素A,根据第二个数组中的相应元素B,计算A^B |
maximum、fmax | 元素级的最大值计算。fmax将忽略NaN |
minimum、fmin | 元素级的最小值计算。fmin将忽略NaN |
mod | 元素级的求模计算(除法的余数) |
copysign | 将第二个数组中的值的符号复制给第一个数组中的值 |
greater、greater_equal、less、less_equal | 执行元素级的比较运算,最终产生布尔型数组。相当于中缀运算符 >, >=, <, <=, ==, != |
logical_and、logical_or | 执行元素级的真值逻辑运算。相当于中缀运算符 & | ^ |
10. 视图、副本总结
返回源数据视图:
- arr[:3](基本索引)
- arr[2:5, :3](高维度索引)
返回新数组:
- arr.astype('f8')(类型转换)
- arr[:3].copy()(生成副本)
- arr[bools](布尔型索引)
- arr[[3, 2, 0]](花式索引)
参考文献
《利用Python进行数据分析》
作者:Wray Zheng
原文:http://www.codebelief.com/article/2017/03/python-data-analysis-numpy-ndarray/