3.9大型数组运算

问题:

​ 你需要在数据集(比如数组或网格)上面执行计算:

解决方案:

​ 涉及到数组的重量级运算操作,可以使用NumPy库。NumPy的一个主要特征是它会给Python提供一个数组对象,相比标准的Python列表已更适合用来做数学运算。下面是一个简单的小例子,向你展示标准列表对象和NumPy数组之间的差别:

x = [1, 2, 3, 4]
y = [5, 6, 7, 8]
print(x * 2)  #->[1, 2, 3, 4, 1, 2, 3, 4]
# print(x + 10)
print(x+y)  # ->[1, 2, 3, 4, 5, 6, 7, 8]
import numpy as np

ax=np.array([1,2,3,4])
ay=np.array([5,6,7,8])
print(ax*2)  # ->[2 4 6 8]
print(ax+10)  #->[11 12 13 14]
print(ax+ay)# ->[ 6  8 10 12]
print(ax*ay)# ->[ 5 12 21 32]

​ 正如所见,两种方案中数组的基本数学运算结果并不相同。特别的,Numpy中的标量运算(比如ax*2或ax+10)会作用在每个元素上。另外,当两个操作数都是数组的时候执行元素对等位置计算,并最终生成一个新的数组。

​ 对整个数组中所有元素同时执行数学运算可以使得作用在整个数组上的函数运算简单而又快速。比如,如果你想计算多项式的值,可以这样做:

def f(x):
    return 3*x**2 -2*x+7
print(f(ax))  #->[ 8 15 28 47]

​ Numpy还为数组操作提供了大量的通用函数,这些函数可以作为math模块中类似函数的替代。比如:

print(np.sqrt(ax))  #->[1.         1.41421356 1.73205081 2.        ]

print(np.cos(ax))#->[ 0.54030231 -0.41614684 -0.9899925  -0.65364362]

​ 使用这些通用函数要比循环数组并使用math模块中的函数执行计算要快的多。因此,只要可能额话尽量多选则numpy的数组方案。

​ 底层实现中,Numpy数组使用功能了C或Fortan语言的机制分配内存。也就是说,它们是一个非常大的连续的并由同类型数组组成的内存区域。所以,你可以构造一个比普通pyhton列表大的多的数组。比如,如果你想构造一个1000*10000的浮点数二维网格,很轻松。

print(np.zeros(shape=(10000,10000),dtype=float))
'''
[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]

'''

所有的普通操作还是会同时作用在所有元素上:

grid=np.zeros(shape=(10000,10000),dtype=float)
print(grid)
'''
[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]

'''
grid+=10
print(grid)
'''
[[10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 ...
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]]
'''
print(np.sin(grid))
'''
[[-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 ...
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]
 [-0.54402111 -0.54402111 -0.54402111 ... -0.54402111 -0.54402111
  -0.54402111]]

'''

​ 关于Numpy有一点需要特别的注意,那就是它扩展Python列表的索引功能。特别是对于多维数组。为了说明清楚,先构造一个简单的二维数组并试着做些实验。

a=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(a)
'''
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

'''
print(a[1])
print(a[:,1])
'''
[5 6 7 8]
[ 2  6 10]
'''
print(a[1:3,1:3])
'''
[[ 6  7]
 [10 11]]
'''
a[1:3,1:3]+=10
print(a)
'''
[[ 1  2  3  4]
 [ 5 16 17  8]
 [ 9 20 21 12]]

'''
print(a+[100,101,102,103])
'''
[[101 103 105 107]
 [105 117 119 111]
 [109 121 123 115]]
'''
print(a)
'''
[[ 1  2  3  4]
 [ 5 16 17  8]
 [ 9 20 21 12]]
'''
print(np.where(a<10,a,10))
'''

[[ 1  2  3  4]
 [ 5 10 10  8]
 [ 9 10 10 10]]
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值