numpy
numpy
数组:array
很多其他科学计算的第三方库都是以 Numpy 为基础建立的。
Numpy 的一个重要特性是它的数组计算。
使用前一定要先导入 Numpy 包,导入的方法有以下几种:
import numpy
import numpy as np
from numpy import *
from numpy import array, sin
导入 numpy,最常用为这种:
import numpy as np
假如我们想将列表中的每个元素增加 1,但列表不支持这样的操作(报错):
a = [1, 2]
# a + 1 # 报错
使用 numpy.array:
a = np.array(a)
a # [1 2]
b = a + 1
b # array([2,3])
与另一个 array 相加,得到对应元素相加的结果:
c = a + b
print(c) # array([3,5])
# 对应元素相乘:
print(a * b) # [2 6]
# 对应元素乘方:
print(a ** b) # [1 8]
数组的合并
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.arange(2) # np.array([0, 1])
print(a, b)
'''[[1 2]
[3 4]] [0 1]'''
# 正确的做法是:
np.append(a, b) # array([1, 2, 3, 4, 0, 1])
# 错误的做法是:
print(list(a)+ list(b)) # [array([1, 2]), array([3, 4]), 0, 1]
提取数组中的元素
# 提取第一个
a = np.array([1, 2, 3, 4])
print(a[0]) # 1
# 提取前两个元素:
print(a[:2]) # [1 2]
# 最后两个元素
print(a[-2:]) # [3 4]
# 相加:
print(a[:2] + a[-2:]) # [4 6]
修改数组形状
查看 array 的形状:
b = a.shape
b # (4,)
# 修改 array 的形状:
a.shape = 2, 2
a
# [[1 2]
# [3 4]]
# 多维数组
# a 现在变成了一个二维的数组,可以进行加法:
a + a
# [[2 4]
# [6 8]]
# 乘法仍然是对应元素的乘积,并不是按照矩阵乘法来计算:
a * a
# [[ 1 4]
# [ 9 16]]
Numpy 索引:index
import numpy as np
# 查看形状,会返回一个元组,每个元素代表这一维的元素数目:
a = np.array([1, 2, 3, 5])
# 1维数组,返回一个元组
a.shape
# 查看元素数目:
a.size
使用 fill 方法设定初始值
可以使用 fill 方法将数组设为指定值:
print(a)
a.fill(-4)
print(a)
# 切片,支持负索引:
a = np.array([11, 12, 13, 14, 15])
print(a[1:-2]) # [12 13]
# 省略参数:
print(a[::2]) # [11 13 15]
print(a[-2:]) # array([14, 15])
假设我们记录一辆汽车表盘上每天显示的里程数:
rec = np.array([21000, 21180, 21240, 22100, 22400])
dist = rec[1:] - rec[:-1] # 后一天减去前一天的
dist
多维数组的索引
a = np.array([[1, 2, 3], [7, 8, 9]])
a
# 查看形状:
print(a.shape)
# 查看总的元素个数:
print(a.size)
# 查看维数:
print(a.ndim)
# 对于二维数组,可以传入两个数字来索引:
print(a[1, 1])
# 索引一整行内容:
print(a[0])
多维数组的复杂一点的例子:
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
# 想得到第一行的第 4 和第 5 两个元素:
print(a[0, 3:5]) # [3 4]
# 得到最后两行的最后两列:
print(a[4:, 4:]) # [[44 45][54 55]]
# 得到第三列:
print(a[:, 2]) # [ 2 12 22 32 42 52]
取出 3,5 行的奇数列:
b = a[2::2, ::2]
b
切片在内存中使用的是引用机制
引用机制意味着,Python 并没有为 b 分配新的空间来存储它的值, 而是让 b 指向了 a 所分配的内存空间,因此,改变 b 会改变 a 的值:
a = np.array([0, 1, 2, 3, 4])
b = a[2:4]
b
b[0] = 10
b
a
# 而这种现象在列表中并不会出现:
b = a[2:3]
b[0] = 12
print(a)
# 解决方法是使用copy()方法产生一个复制,这个复制会申请新的内存:
b = a[2:4].copy()
b[0] = 10
print(a, b)
一维花式索引
与 range 函数类似,我们可以使用 arange 函数来产生等差数组。
a = np.arange(0, 80, 10)
a
# 花式索引需要指定索引位置:
indices = [1, 2, -3]
y = a[indices]
y
# 还可以使用布尔数组来花式索引:
mask = np.array([0, 1, 1, 0, 0, 1, 0, 1], dtype=bool)
a[mask] # [10 20 50 70]
选出了所有大于 0.5 的值:
from numpy.random import rand
a = rand(10)
a
mask = a > 0.5
a[mask]
“不完全”索引
只给定行索引的时候,返回整行:
a = np.array([[0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
b = a[:3]
b
# 这时候也可以使用花式索引取出第2,3,5行:
condition = np.array([0, 1, 1, 0, 1, 0], dtype=bool)
c = a[condition]
c
where 语句
where(array)
where 函数会返回所有非零元素的索引。
a = np.array([1, 2, 4, 6])
a > 2 # [False False True True]
b = np.where(a > 2)
b # 返回的是索引位置
# 注意到 where 的返回值是一个元组。
index = np.where(a > 2)[0]
print(index) # [2 3]
# 可以直接用 where 的返回值进行索引:
loc = np.where(a > 2)
b = a[loc]
print(b) # [4 6]
考虑二维数组:
a = np.array([[0, 12, 5, 20],
[1, 2, 11, 15]])
loc = np.where(a > 10)
print(loc) # (array([0, 0, 1, 1]), array([1, 3, 2, 3]))
# 也可以直接用来索引a:
b = a[loc]
print(b) # [12 20 11 15]
或者可以这样:
rows, cols = np.where(a > 10)
print(rows)
print(cols)
print(a[rows, cols])
例子:
a = np.arange(20)
a.shape = 5, 4
a
a > 12
b = np.where(a > 12)
b
# (array([3, 3, 3, 4, 4, 4, 4]), array([1, 2, 3, 0, 1, 2, 3]))
a[b] # [13 14 15 16 17 18 19]
Numpy 方法
Numpy 的常用方法。
import numpy as np
a = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])
a
for row in a:
print(row)
所有元素的 迭代器:
for i in a.flat:
print(i)