Numpy数组进阶_Python数据分析与可视化

Numpy的广播机制

广播 (Broadcast) 是 numpy 对不同形状 (shape) 的数组,进行数值计算的方式。 对数组的算术运算通常在相应的元素上进行,当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。

如图:
在这里插入图片描述

广播的规则

  1. 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐;
  2. 输出数组的形状是输入数组形状的各个维度上的最大值;
  3. 如果输入数组的某个维度和输出数组的对应维度的长度相同,或者其长度为 1 时,这个数组能够用来计算,否则出错;
  4. 当输入数组的某个维度的长度为 1 时,沿着此维度运算,都用此维度上的第一组值。

示例:

arr1 = np.array([[0,0,0],[1,1,1],[2,2,2]])
arr2 = np.array([1,2,3])
print('arr1:\n',arr1)
print('arr2:\n',arr2)
print('arr1+arr2:\n',arr1+arr2)
#输出结果
arr1:
[[0 0 0]
[1 1 1]
[2 2 2]]
arr2:
[1 2 3]
arr1+arr2:
[[1 2 3]
[2 3 4]
[3 4 5]]

高级索引

NumPy 比一般的 Python 序列提供更多的索引方式。除了基本的用整数和切片的索引外,数组还有整数数组索引、布尔索引及花式索引。

整数数组索引

以下实例获取数组中 (0,0),(1,1) 和 (2,0) 位置处的元素。

In : x = np.arange(12).reshape((4,3))
In : y = x[[0, 1, 2],[0, 1, 0]]
In : y
Out: array([0, 4, 6])

布尔索引

以下实例获取数组中大于 7 的元素。

In : x = np.arange(12).reshape((4,3))
In : y = x[x > 7]
In : y
Out: array([8, 9, 10, 11])

花式索引

花式索引指的是利用整数数组进行索引。

花式索引根据索引数组的值,作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。

花式索引跟切片不一样,它总是将数据复制到新数组中。

传入单个索引数组
以下实例获取数组的第 5、1、2、3 行。

In : x = np.arange(15).reshape((5,3))
In : y = x[[4, 0, 1, 2]]
In : y
Out: array([12, 13, 14]
           [0, 1, 2]
           [3, 4, 5]
           [6, 7, 8])

传入多个索引数组
传入多个索引数组,则需要和 numpy.ix_ 同时使用。
numpy.ix_:传入两个参数,第一个参数为数组索引,第二个参数为排列顺序。

In : x = np.arange(12).reshape((4,3))
In : y = x[np.ix_([1, 2],[2, 1, 0])]
In : y
Out: array([5, 4, 3]

数组迭代

NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。利用nditer对象可以实现完成访问数组中的每一个元素,这项最基本的功能,使用标准的 Python 迭代器接口,可以逐个访问每一个元素。

In : x = np.arange(6).reshape(2, 3)
In : for y in np.nditer(x):
         print(y, end=" ")
Out:
0 1 2 3 4 5

控制迭代顺序
nditer 对象提供了一个命令参数,来控制迭代输出顺序,默认值是 ‘K’,即 order=‘k’。该默认值表示,按在存储器中的顺序输出。
同时 nditer 中,还提供了两个参数,控制迭代器输出顺序:

for x in np.nditer(a, order='F') # Fortran order,即是列序优先;
for x in np.nditer(a.T, order='C') # C order,即是行序优先;

修改数组元素值
默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,必须将可选参数 op_flags 指定为 read-write 或者 write-only 的模式。

In : x = np.arange(6).reshape(2, 3)
In : for y in np.nditer(x, op_flags=["readwrite"]):
         y[...] = 2 * y
In : print(x)
Out:
array([[ 0,  2,  4]
       [ 6,  8, 10]])

使用外部循环
将一维的最内层的循环转移到外部循环迭代器,使得 numpy 的矢量化操作,在处理更大规模数据时,变得更有效率。

In : x = np.arange(6).reshape(2, 3)
In : for y in np.nditer(x, flags=['external_loop'], order='F'):
         print(y)
Out:
[0, 3]
[1, 4]
[2, 5]

广播迭代
如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 34,数组 b 的维度为 14,则使用以下迭代器(数组 b 被广播到 a 的大小)。

In : a = np.arange(12).reshape(3, 4)
In : b = np.arange(4)
In : for x, y in np.nditer([a, b]):
         print("{}:{}".format(x,y), end=", ")
Out:
0:1, 1:2, 2:3, 3:4, 4:1, 5:2, 6:3, 7:4, 8:1, 9:2, 10:3, 11:4,
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿松爱睡觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值