Numpy数组的切片、索引和运算
ndarray数组的切片和索引
基础索引
一维数组切片和索引
和Python的List一样
ndarray 数组可以基于0 - n 的下标进行索引,并设置start, stop 及step 参数进行,从原数组中切割出一个新数组。
- 注意:切片的修改会修改原来的数组
- 原因:Numpy经常要处理大数组,避免每次都复制
import numpy as np
a = np.arange(8)
print(a[0]) # 输出 0
print(a[-1]) # 输出 7
print(a[1:6:2]) # 输出 [1 3 5]
print(a[:]) # 输出 [0 1 2 3 4 5 6 7]
print(a[::-1]) # 输出 [7 6 5 4 3 2 1 0]
二维数组切片和索引
# 二维向量,一般用大写字母
X = np.arange(20).reshape(4,5)
# 分别用行坐标、列坐标,实现行列筛选
# X[0][0]
X[0, 0]
X[-1, 2]
# 可以省略后续索引值,返回的数据是降低一个维度的数组
# 这里的2,其实是要筛选第2行
X[2]
# 筛选-1对应的行
X[-1]
# 筛选多行
X[:-1]
# 筛选多行,然后筛选多列
X[:2, 2:4]
import numpy as np
a = np.arange(1,10).reshape(3,3) # [[1 2 3] [4 5 6] [7 8 9]]
print(a[2]) # 获取第三行 输出:[ 7 8 9]
print(a[1][2]) # 获取第二行 第三列 输出:6
print(a[1,2]) # 获取第二行 第三列 输出:6
print(a[:,1]) # 获取所有行 第2列 输出:[2 5 8]
print(a[::2,:]) # 获取奇数行,所有列 输出: [[1 2 3] [7 8 9]]
print(a[::-1,::-1]) # 行列倒序 输出: [[9 8 7] [6 5 4] [3 2 1]]
布尔索引
一维数组的布尔索引
import numpy as np
a = np.arange(1,10)
b = a > 5
print(b) # 输出: [False False False False False True True True True]
print(a[b]) # 输出: [6 7 8 9]
a[a<=5] = 0
a[a>5] += 100
print(a) # 输出: [0 0 0 0 0 106 107 108 109]
二维数组的布尔索引
把特征满足某些条件的数据(行)筛选出来
# 举例:怎样把第3列大于5的行筛选出来
X[:, 3]
# 这里是按照行进行的筛选
X[X[:, 3]>5]
import numpy as np
a = np.arange(1,7).reshape(2,3)
# a[:,1]筛选出所有行第二列
a[:,1][a[:,1]>3] +=100 # 所有行,第二列>3的值+100
print(a) # 输出: [[ 1 2 3] [4 105 6]]
神奇索引
使用整数数组进行数据索引。
与切片不同,花式索引返回的是对象的一个复制而不是引用
一维数组的神奇索引
import numpy as np
a = np.arange(7)
print(a[[1,3,5]]) # 输出:[1 3 5]
二维数组的神奇索引
import numpy as np
a = np.arange(1,7).reshape(2,3)
print(a) # 输出:[[1 2 3] [4 5 6]]
print(a[[0,1],[0,2]]) # 0行0列和1行2列对应的元素 输出:[1,6]
print(a[:,[0,2]]) # 输出:[[1 3] [4 6]]
ndarray对象的运算
ndarray对象的算术运算
加减乘除,代码如下:
import numpy as np
a = np.arange(1,10).reshape(3,3) # [[1 2 3] [4 5 6] [7 8 9]]
b = np.array([1,1,1])
c = a + b # 广播
d = np.add(a,b) # add(),subtract(),multiply(),divide()
print(c) # 输出[[ 2 3 4] [ 5 6 7] [ 8 9 10]]
print(d) # 输出[[ 2 3 4] [ 5 6 7] [ 8 9 10]]
ndarray对象的数学函数
| 数学运算函数 | 描述 |
|---|---|
| np.abs /fabs | 绝对值 |
| np.add(x1,x2 ) | 按元素添加参数,等效于 x1 + x2 |
| np.subtract(x1,x2) | 按元素方式减去参数,等效于x1 - x2 |
| np.multiply(x1,x2) | 逐元素乘法参数,等效于x1 * x2 |
| np.divide(x1,x2) | 逐元素除以参数,等效于x1 / x2 |
| np.exp(x) | 计算e的x次方。 |
| np.exp2(x) | 计算2的x次方。 |
| np.power(x1,x2) | 计算x1的x2次幂。 |
| np.mod(x) | 返回输入数组中相应元素的除法余数. |
| np.log(x) | 自然对数,逐元素。 |
| np.log2(x) | x的基础2对数。 |
| np.log10(x) | 以元素为单位返回输入数组的基数10的对数。 |
| np.expm1(x) | 对数组中的所有元素计算exp(x) - 1 |
| np.log1p(x) | 返回一个加自然对数的输入数组。 |
| np.sqrt(x) | 按元素方式返回数组的正平方根。 |
| np.square(x) | 返回输入的元素平方。 |
| np.sin(x) | 三角正弦。 |
| np.cos(x) | 元素余弦。 |
| np.tan(x) | 逐元素计算切线。 |
| np.round(x) | 四舍五入 |
| np.floor(x) | 向下取整 |
| np.ceil(x) | 向上取整 |
代码如下:
import numpy as np
a = np.arange(1,6)
print(a) # 输出: [1 2 3 4 5]
print(np.abs(a)) # 输出: [1 2 3 4 5]
print(np.sqrt(a)) # 输出: [1. 1.41421356 1.73205081 2. 2.23606798]
print(np.power(a, 3)) # 输出: [ 1 8 27 64 125]
print(np.exp(a)) # 输出: [ 2.71828183 7.3890561 20.08553692 54.59815003 148.4131591 ]
print(np.log(a)) # 以e为底 输出: [0. 0.69314718 1.09861229 1.38629436 1.60943791]
ndarray对象的取整函数
np.random.seed(123)
arr = np.random.randn(8)
# np.round 与 np.around 相同
arr_a = np.around(arr, 2) # 四舍五入
arr_f = np.floor(arr) # 向下取整
arr_c = np.ceil(arr) # 向上取整
arr_a
arr_f
arr_c
ndarray对象的统计函数
| 函数名称 | NaN安全版本 | 描述 |
|---|---|---|
| np.sum() | np.nansum() | 计算元素的和 |
| np.min() | np.nanmin() | 找出最小值 |
| np.max() | np.nanmax() | 找出最大值 |
| np.prod() | np.nanprod() | 计算元素的积 |
| np.ptp() | N/A | 计算元素的极差(最大值 - 最小值) |
| np.mean() | np.nanmean() | 计算元素的算术平均值 |
| np.std() | np.nanstd() | 计算标准差 |
| np.var() | np.nanvar() | 计算方差 |
| np.percentile() | np.nanpercentile() | 计算百分位数 |
| np.median() | np.nanmedian() | 计算中位数 |
| np.average() | N/A | 返回数组的加权平均值 |
| np.any() | N/A | 验证任何一个元素是否为真 |
| np.all() | N/A | 验证所有元素是否为真 |
关于NaN安全版本的说明:数组出现NaN空值将影响最终结果输出,如果不希望空值带入计算,则可使用NaN安全版本
| 方法 | 说明 |
|---|---|
| np.argmin( ) | 最小值的索引 |
| np.argmax( ) | 最大值的索引 |
| np.average( ) | 加权平均 |
代码如下:
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
np.min(a) # 所有元素中最小的元素
np.min(a, axis = 0) # 每一列中最小的元素
np.max(a, axis = 1) # 每一行中最大的元素
import numpy as np
a = np.arange(1,6)
print(a) # 输出: [1 2 3 4 5]
print(np.sum(a)) # 输出: 15
print(np.mean(a)) # 输出: 3.0
print(np.std(a)) # 输出: 1.4142135623730951
print(np.var(a)) # 输出: 2.0
print(np.median(a)) # 输出: 3.0
print(np.min(a)) # 输出: 1
print(np.max(a)) # 输出: 5
print(np.average(a,weights=np.ones(5))) # 输出: 3.0
arr = np.arange(12).reshape(3,4)
np.percentile(arr, [25, 50, 75])
np.quantile(arr, [0.25, 0.5, 0.75])
ndarray对象的排序和索引函数
np.sort
np.random.seed(123)
arr = np.random.randint(1,30,9)
arr_a = np.sort(arr) # 也可在不同维度上进行索引
np.argsort
argsort返回从小到大的排列在数组中的索引位置
#电影名称
mv_name=['肖申克的救赎','控方证人','美丽人生','阿甘正传','霸王别姬','泰坦尼克号','辛德勒的名单','这个杀手不太冷','疯狂动物成','海豚湾']
#评分人数
mv_num=np.array([692795,42995,327855,580897,478523,157074,306904,662552,284652,159302])
order=np.argsort(mv_num)
mv_name[order[0]] # 获取评分人数最少的电影名称
np.nonzero
arr = np.array([0,2,3,0,7,0])
np.nonzero(arr) # 返回的是非零元素在原数组中的位置
arr[np.nonzero(arr)]
np.where
where函数会返回所有非零元素(满足条件)的索引
np.random.seed(123)
arr = np.random.randint(1,30,9)
arr2 = np.random.randint(6,20,9)
arr
arr2
np.where(arr>5) # 返回的是位置信息
arr[np.where(arr>5)]
arr[arr>5] # 与 arr[np.where(arr>5)] 等价
np.where(arr>arr2,arr,arr2)
ndarray对象的唯一化和集合运算
# 唯一化
np.random.seed(123)
arr = np.random.randint(1,30,9)
np.unique(arr)
np.random.seed(123)
arr = np.random.randint(1,30,9)
arr2 = np.random.randint(6,20,9)
np.in1d(arr, arr2) # 判断元素是否在数组中
np.intersect1d(arr, arr2) # 求交集
np.union1d(arr, arr2) # 求并集
np.setdiff1d(arr, arr2) # 求差集
ndarray对象的矢量化(向量化)运算
数组表达式替换显式循环的做法通常称为向量化。
矢量化代码有很多优点,其中包括:
1、矢量化代码更简洁易读
2、更少的代码行通常意味着更少的错误
3、执行效率高,运行速度快
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])
print(arr1+arr2) # 输出: [5,7,9]
Numpy的广播功能
1、如果数组不具有相同的秩,则将较低等级数组的形状维度添加1,直到两个形状具有相同的大小。即如果运算双方都是数组,而且数组的形状不一致,那么,两个数组各自向一个广播,广播后的两个数组形状相同,则广播可行。
2、其中一个数组的维度大小和元素个数为1,相当于对单个标量进行广播。即如果运算的双方一方是数组,一方是标量(单个的数值),不受广播方向约束,标量可以向两个方向广播。
3、在一个数组的大小为1且另一个数组的大小大于1的任何维度中,第一个数组的行为就像沿着该维度复制一样。即如果运算的双方都是数组,而且数组的形状不一致,那么,一个数组向一个方向广播之后可以得到和另一个数组一样的形状,则广播可行。

本文详细讲解了Numpy数组的一维和二维切片、基础索引,以及布尔索引的使用方法。此外,还介绍了神奇索引、算术运算、数学函数、取整、统计分析和排序功能,以及广播机制在向量化操作中的应用。
2728

被折叠的 条评论
为什么被折叠?



