Numpy数组的切片、索引和运算

本文详细讲解了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的任何维度中,第一个数组的行为就像沿着该维度复制一样。即如果运算的双方都是数组,而且数组的形状不一致,那么,一个数组向一个方向广播之后可以得到和另一个数组一样的形状,则广播可行。
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值