3.数组的运算
数组的运算支持向量化运算。
数组和标量间的运算
数组之所以很强大,是因为不需要通过循环就可以完成批量计算。
a = [1, 2, 3]
b = []
for iin a:
b.append(i*i)
print(‘b数组:’, b)
w = np.array([1, 2, 3])
c = w*2
print(‘c数组:’, c)
输出:
b数组: [1, 4, 9]
c数组: [2 4 6]
ufunc函数
通用函数,是一种能够对数组中的所有元素进行操作的函数。
常用的ufunc函数比使用math库中的函数效率要高很多。有四则运算,比较运算,逻辑运算。
四则运算的每个数组形状必须相同,因为对数组中的每个元素进行的。
逻辑:np.any 函数表示逻辑或,np.all函数表示逻辑与
四则运算:
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(“x :”, x)
print("y: ", y)
print("相加: ", x+y)
print("相减: ", x-y)
print("相乘: ", x*y)
print("幂运算: ", x**y)
输出:
x : [1 2 3]
y: [4 5 6]
相加: [5 7 9]
相减: [-3 -3 -3]
相乘: [ 4 10 18]
幂运算: [ 1 32 729]
比较运算:
x = np.array([1, 3, 6])
y = np.array([2, 3, 4])
print(“x :”, x)
print("y: ", y)
print("<: ", x < y)
print("> :", x > y)
print("==: ", x == y)
print("!= ", x != y)
输出:
x : [1 3 6]
y: [2 3 4]
<: [ True False False]
> : [False False True]
==: [False True False]
!= [ True False True]
ufunc 函数的广播机制
广播是只不同形状的数组之间执行算术运算的方式,广播机制需要遵循4个原则:
1. 让所有输入数组都向其中Shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐
2.输出数组的shape是输入数组shape的各个轴上的最大值
3.如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。
4.当输入数组的某个轴的长度为1时,沿着次轴运算时都用次轴上的第一组值。
a1 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
a2 = np.array([1, 2, 3])
print(‘a1:\n’, a1)
print(‘a2:\n’, a2)
print(‘a1+a2:\n’, a1+a2)
输出:
a1:
[[0 0 0]
[1 1 1]
[2 2 2]]
a2:
[1 2 3]
a1+a2:
[[1 2 3]
[2 3 4]
[3 4 5]]
条件逻辑运算
a1 = np.array([1, 3, 5, 7])
a2 = np.array([2, 4, 6, 8])
cond = np.array([True, False, True, False])
result = [(xif celse y)for x, y, cin zip(a1, a2, cond)]
print(result)
输出:
[1, 4, 5, 8]
这种方法对大规模数组处理效率不高,无法用于多维数组,NumPy提供的Where方法可以克服这个问题。
np.where(condition,x ,y) 表示条件满足输出x,不满足输出y
result = np.where([[True, False], [True, True]], [[1, 2], [3, 4]], [[9, 8], [7, 6]])
print(result)
输出:
[[1 8]
[3 4]]
w = np.array([2, 5, 6, 3, 10])
r = np.where(w >4)
print®
输出:
(array([1, 2, 4], dtype=int64),)
where中只有条件,没有x,y 则输出满足条件的元素的坐标。
4. 数组的读与写
读/写二进制文件
从二进制文件中读取数据,NumPy.load(“文件名.npy”)
以二进制格式保存数据,NumPy.save(“文件名[.npy]”, arr)
它们会自动处理元素类型和Shape信息,使用它们读写数组非常方便。
数组的读写
a = np.arange(1, 13).reshape(3, 4)
print(a)
np.save(‘arr.npy’, a)
c = np.load(‘arr.npy’)
print©
输出:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
多个数组保存
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
print©
np.savez(‘result.npz’, a, b, sin_array=c)
r = np.load(‘result.npz’)
print®
print(r[‘arr_0’])
输出:
[0. 0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
0.56464247 0.64421769 0.71735609 0.78332691]
<numpy.lib.npyio.NpzFile object at 0x00000255A3244FA0>
[[1 2 3]
[4 5 6]]
读写文本文件
把文件加载到一个二维数组中, NumPy.load("…/tmp/arr.txt", delimiter=",")
将数组写到某个分隔符隔开的文本文件中,NumPy.savetxt("…/tmp/arr.txt",arr, fmt="%d",delimiter=",")
结构化数组和缺失数据, NumPy.genfromtxt("…/tmp/arr.txt", delimiter=",")
a = np.arange(0, 12, 0.5).reshape(4, -1)
np.savetxt(“a1-out.txt”, a)
# 默认安装%.18e格式保存
np.loadtxt(“a1-out.txt”)
np.savetxt(“a2-out.txt”, a, fmt="%d", delimiter=",")
# 改为保存整数,以逗号分隔
np.loadtxt(“a2-out.txt”, delimiter=",")
a1-out.txt:
0.000000000000000000e+00 5.000000000000000000e-01 1.000000000000000000e+00 1.500000000000000000e+00 2.000000000000000000e+00 2.500000000000000000e+00
3.000000000000000000e+00 3.500000000000000000e+00 4.000000000000000000e+00 4.500000000000000000e+00 5.000000000000000000e+00 5.500000000000000000e+00
6.000000000000000000e+00 6.500000000000000000e+00 7.000000000000000000e+00 7.500000000000000000e+00 8.000000000000000000e+00 8.500000000000000000e+00
9.000000000000000000e+00 9.500000000000000000e+00 1.000000000000000000e+01 1.050000000000000000e+01 1.100000000000000000e+01 1.150000000000000000e+01
a2-out.txt:
0,0,1,1,2,2
3,3,4,4,5,5
6,6,7,7,8,8
9,9,10,10,11,11
读取CSV文件
loadtxt(fname, dtype= ,comments =’#’,delimiter=None, converters=None, skiprows =0, usecols=None,unpack=False,ndim=0, econding=‘bytes’)
主要参数:
fname: str,读取CSV文件名
delimiter: str, 数据的分隔符
usecols: Tuple(元组),执行加载数据文件中的哪些列
unpack: bool,是否将加载的数据拆分为多个组,True表示拆分,False表示不拆
skiprows: int,跳过多少行,一般用于跳过前几行的描述性文字
encoding: bytes,编码格式