Python 数据分析:numpy 多维数组 ndarray

下面的文章中,将使用约定俗成的模块名 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进行数据分析》

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注