Numpy
一、定义
一个基于python的扩展库
提供高维数组对象ndarray,运算速度碾压python List
提供了各种高级数据编程工具,如矩阵运算、向量运算、快速筛选、IO操作、傅里叶变换、线性代数、随机数等
二、属性
- ndim:维度
- shape:形状(各维度的长度)
- size:总长度
- dtype:元素类型
三、初始numpy
1、创建 ndarray
import numpy as np
arr1 = np.array([1,2,3])
type(arr1)
>>输出结果:<class 'numpy.ndarray'>
arr1.ndim
>>输出结果:1
arr1.shape
>>输出结果:(3,)
arr1.size
>>输出结果:3
arr1.dtype
>>输出结果:int32
arr2 = np.array([[1,2,3],[2,3,4]])
arr2.ndim, arr2.shape, arr2.size, arr2.dtype
>>输出结果:
2 (2, 3) 6 int32
2.强制类型统一
numpy设计初衷是用于运算的,所以对数据类型进行统一优化。
注意:
- numpy 默认 ndarray 的所有元素的类型是相同的。
- 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str > float > int 。
list1 = [1,2,3, 4.12]
print(list1)
>>输出结果:[1,2,3, 4.12]
arr1 = np.array(list1)
print(arr1)
>>输出结果:[1. 2. 3. 4.12]
arr1.dtype
>>输出结果:float64
3. numpy 中的数据类型
名称 描述
bool_ 布尔型数据类型(True 或者 False)
int_ 默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc 与 C 的 int 类型一样,一般是 int32 或 int 64
intp 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8 字节(-128 to 127)
int16 整数(-32768 to 32767)
int32 整数(-2147483648 to 2147483647)
int64 整数(-9223372036854775808 to 9223372036854775807)
uint8 无符号整数(0 to 255)
uint16 无符号整数(0 to 65535)
uint32 无符号整数(0 to 4294967295)
uint64 无符号整数(0 to 18446744073709551615)
float_ float64 类型的简写
float16 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_ complex128 类型的简写,即 128 位复数
complex64 复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128 复数,表示双 64 位浮点数(实数部分和虚数部分)
4. 使用 numpy 的 routines 函数创建 ndarray
4.1 np.ones(shape, dtype=None, order=‘C’),shape: 形状,使用元组表示
arr1 = np.ones(shape=(2,3))
print(arr1)
>>输出结果:
[[1. 1. 1.]
[1. 1. 1.]]
arr1 = np.ones(shape=(3,))
print(arr2)
>>输出结果:
[1., 1., 1.]
arr3 = np.ones(shape=(1,3))
print(arr3)
>>输出结果:
[[1., 1., 1.]]
arr4 = np.ones(shape=(3,1))
print(arr4)
>>输出结果:
[[1.],
[1.],
[1.]]
arr5 = np.ones(shape=(3,2), dtype=np.int8)
print(arr5。dtype)
>>输出结果:
int8
4.2 np.zeros(shape, dtype=float, order=‘C’)
arr = np.zeros(shape=(3,1),dtype=np.uint8)
print(arr,arr.dtype)
>>输出结果:
[[0]
[0]
[0]] uint8
4.3 np.full(shape, fill_value, dtype=None, order=‘C’)
arr = np.full(shape=(3,3), fill_value=6)
print(arr)
>>输出结果:
[[6 6 6]
[6 6 6]
[6 6 6]]
4.4 np.eye(N, M=None, k=0, dtype=float)
N表示行数,M表示列数,k表示对角线的偏移量
arr1 = np.eye(N=3)
print(arr1)
>>输出结果:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
arr2 = np.eye(N=3,M=4)
print(arr2)
>>输出结果:
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]]
arr3 = np.eye(N=3,k=1)
print(arr3)
>>输出结果:
[[0. 1. 0.]
[0. 0. 1.]
[0. 0. 0.]]
4.5 np.linspace(start, stop, num endpoint=True, retstep=False, dtype=None)
start:起始值,stop:终止值,num:生成数量,endpoint:是否包含终值,默认包含,retstep:是否显示步长,默认不显示
arr1 = np.linspace(0, 10, 11)
print(arr1)
>>输出结果:
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
arr2 = np.linspace(0, 100, 10, endpoint=False)
print(arr2)
>>输出结果:
[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90.]
arr3 = np.linspace(0, 10, 11, retstep=True)
print(arr3)
>>输出结果:
(array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]), 1.0)
4.6 np.arange(start, stop, step, dtype=None)
arr = np.arange(0, 100, step=10)
print(arr)
>>输出结果:
[ 0 10 20 30 40 50 60 70 80 90]
4.7 np.random.randint(low, high=None, size=None, dtype=‘l’)
arr1 = np.random.randint(low=0, high=100, size=(3,5))
print(arr1)
>>输出结果:
[[71 77 21 50 22]
[97 2 76 15 88]
[39 65 35 83 31]]
arr2 = np.random.randint(0,10, size=(10,))
print(arr2)
>>输出结果:
[7 4 1 0 0 8 8 8 9 3]
4.8 正态分布函数
4.8.1 np.random.normal( loc , scale , size ) 普通正态分布
loc:分布的均值(中心),scale:分布的标准差(宽度),size:数据的维度
arr1 = np.random.normal(loc=175, scale=10, size=(10,))
print(arr1)
>>输出结果:
[181.82099125 165.95232532 174.28611612 175.88692564 190.99557938
188.72141845 172.99607932 181.86017743 179.41932145 177.87545193]
4.8.2 np.random.randn(d0, d1, …, dn) 标准正态分布
loc = 0 ,scale = 1 的正太分布,dn 表示数据的维度
arr1 = np.random.rand(4,2)
print(arr1)
>>输出结果:
[[0.72600143 0.00204256]
[0.77456368 0.70902766]
[0.13168928 0.37441316]
[0.36387004 0.78058689]]
arr2 = np.random.rand(4,3,2)
print(arr2)
>>输出结果:
[[[0.33233046 0.09854491]
[0.51708553 0.34565501]
[0.92549466 0.47242487]]
[[0.6345973 0.26929633]
[0.18913436 0.86976257]
[0.24877992 0.70578262]]
[[0.02646144 0.12935062]
[0.40492351 0.12528527]
[0.19876852 0.97161948]]
[[0.09079952 0.87203089]
[0.13185315 0.11456373]
[0.91589346 0.41653486]]]
4.9 np.random.random(size=None)
生成0到1的随机数,左闭右开
arr = np.random.random(size=(10,5))
print(arr)
>>输出结果:
[[0.6399623 0.2894182 0.68055697 0.31633504 0.96599415]
[0.51333444 0.3878091 0.50374029 0.17746228 0.11390883]
[0.5477178 0.60228294 0.8993186 0.03540799 0.7171814 ]
[0.17864351 0.79998941 0.97899478 0.749328 0.88348865]
[0.90883659 0.7320521 0.7149262 0.26934021 0.66994562]
[0.85799539 0.14949797 0.42199284 0.43718203 0.27460366]
[0.51228035 0.81401212 0.37627402 0.21548691 0.83943411]
[0.61688753 0.78208082 0.00106351 0.28748206 0.69535803]
[0.5425586 0.12124555 0.76270666 0.70387453 0.21285709]
[0.73174531 0.32765208 0.97659109 0.81806137 0.3291994 ]]
4.10 np.random.permutation(10)
生成随机索引
arr = np.random.permutation(5)
print(arr)
>>输出结果:
[2 4 3 0 1]
4.11 np.random.seed(num)
在创建随机数组时,如果在np.random.seed()中指定一个参数值,如np.random.seed(2),则每次生成的随机数组都相同
np.random.seed(2) # 添加一个种子
arr = np.random.randint(0, 10, size=5)
print(arr)
>>输出结果:
[8 8 6 2 8]
练习题
-
创建一组形状为(3,4)的二维数组,取值范围为(-5,5)
np.random.randint(-5, 5, size=(3,4))
-
创建一组等差数列,步长为3, 数组长度为5
np.linspace(0, 15, 5, endpoint=False) np.arange(0, 15, step=3)
-
构造一个3维取值范围为0-1的随机数组,数据类型为np.float64,形状为(100,100,3)
data = np.random.random(size=(100, 100, 3))
-
已知Π在numpy中是一个预制的常量,可以使用np.pi访问。计算出将一个圆等分成8份的弧度的代码
np.linspace(0, 2*np.pi, num=8, endpoint=False)
5. ndarray的读写操作
5.1 索引访问
arr4 = np.random.randint(0, 10, size=10)
print(arr4)
>>输出结果:
[6, 5, 7, 4, 4, 0, 5, 6, 1, 2]
print(arr4[0], arr4[-1])
>>输出结果:
6, 2
ndarray的高维数组访问,使用[dim1_index, dim2_index…]
arr5 = np.random.randint(0,10,size=(3,4))
print(arr5)
>>输出结果:
[[6, 2, 4, 1],
[7, 8, 5, 7],
[9, 8, 5, 5]]
print(arr5[2, 1])
>>输出结果:
100
# 注意:在ndarray中尽量不要使用arr5[2][1]这种间接访问 的方式
5.2 列表访问
arr1 = np.random.randint(0, 100, size=10)
print(arr1)
>>输出结果:
[3, 85, 47, 1, 56, 67, 77, 68, 40, 98]
arr1[[1, 2]]
>>输出结果:
[85, 47]
arr1[[1, 2, 1, 2, 1, 2]]
>>输出结果:
[85, 47, 85, 47, 85, 47]
ndarray 也可以同时作为 ndarray对象的索引列表
index2 = np.random.permutation(10)
arr1[index2]
>>输出结果:
[47, 40, 68, 67, 98, 85, 3, 56, 77, 1]
random_index = np.random.permutation(10)[[0,1,2]]
arr1[random_index]
>>输出结果:
[3, 1, 77]
random_index2 = np.random.randint(0, 10, size=3)
arr1[random_index2]
>>输出结果:
[98, 68, 85]
高维数组中的使用
arr2 = np.random.randint(0, 100, size=(5,5))
print(arr2)
>>输出结果:
[[98, 71, 0, 38, 58],
[80, 51, 10, 4, 57],
[58, 86, 97, 21, 18],
[37, 36, 26, 16, 83],
[20, 72, 70, 86, 16]]
arr2[[0, 1]]
>>输出结果:
[[98, 71, 0, 38, 58],
[80, 51, 10, 4, 57]]
arr2[:,[0,1]]
>>输出结果:
[[98, 71],
[80, 51],
[58, 86],
[37, 36],
[20, 72]]
5.3 切片访问
arr1 = np.random.randint(0, 100, size=10)
print(arr1)
>>输出结果:
[3, 85, 47, 1, 56, 67, 77, 68, 40, 98]
arr1[0:3]
>>输出结果:
[3, 85, 47]
arr1[-4:]
>>输出结果:
[77, 68, 40, 98]
arr1[0:-1:2]
>>输出结果:
[3, 47, 56, 77, 40]
arr1[::-1]
>>输出结果:
[98, 40, 68, 77, 67, 56, 1, 47, 85, 3]
5.4 使用bool列表访问
arr3 = np.random.randint(0, 100, size=(5,))
print(arr3)
>>输出结果:
[37, 45, 92, 25, 34]
bool_index = [False, True, False, True, False]
arr3[bool_index]
>>输出结果:
[45, 25]
练习题
-
构建一个长度为10的随机数组,进行逆序输出
data = np.random.random(size=10) print(data, data[::-1]) >>输出结果: [0.72888464, 0.48172442, 0.46580419, 0.71868106, 0.35765977, 0.91799413, 0.14526069, 0.58848584, 0.27973132, 0.00547153] [0.00547153, 0.27973132, 0.58848584, 0.14526069, 0.91799413, 0.35765977, 0.71868106, 0.46580419, 0.48172442, 0.72888464]
-
构造一个形状为(5,4)的二维数组,提取最后两列,使用3种方法
data = np.random.randint(0, 100, size=(5,4)) print(data) >>输出结果: [[ 5, 56, 19, 5], [90, 9, 42, 19], [45, 35, 72, 57], [75, 51, 10, 8], [35, 7, 59, 6]] data2[:,[-2,-1]] data2[:, -2:] data2[:,[False, False, True, True]] >>输出结果: [[19, 5], [42, 19], [72, 57], [10, 8], [59, 6]]
-
构建一个6行5列的数组,对数组进行行方向的随机排序
data = np.random.randint(0, 100, size=(6,5)) print(data) >>输出结果: [[ 1 41 38 11 37] [58 40 12 98 31] [35 65 62 38 1] [46 90 13 26 3] [97 96 50 21 26] [43 72 13 58 73]] row_index = np.random.permutation(6) data[row_index] >>输出结果: [[97 96 50 21 26] [58 40 12 98 31] [ 1 41 38 11 37] [43 72 13 58 73] [35 65 62 38 1] [46 90 13 26 3]]
6. ndarray的级联和切分
6.1 级联
- 级联的参数是列表:一定要加中括号或小括号
- 维度必须相同
- 形状相符
- 级联的方向默认是shape这个tuple的第一个值所代表的维度方向
- 可通过axis参数改变级联的方向
np.concatenate() :
a1 = np.random.randint(0, 10, size=(3,4))
a2 = np.random.randint(10, 20, size=(3,4))
print(a1,a2)
>>输出结果:
[[5, 1, 2, 7],
[1, 6, 5, 6],
[0, 6, 3, 9]]
[[17, 14, 12, 10],
[16, 19, 17, 16],
[15, 12, 11, 10]]
a3 = np.concatenate((a1, a2), axis=0)
print(a3)
>>输出结果:
[[ 5, 1, 2, 7],
[ 1, 6, 5, 6],
[ 0, 6, 3, 9],
[17, 14, 12, 10],
[16, 19, 17, 16],
[15, 12, 11, 10]]
a4 = np.concatenate((a1, a2), axis=1)
print(a4)
>>输出结果:
[[ 5 1 2 7 17 14 12 10]
[ 1 6 5 6 16 19 17 16]
[ 0 6 3 9 15 12 11 10]]
np.hstack与np.vstack
a5 = np.vstack((a1, a4)) # 竖着连接
print(a5)
>>输出结果:
[[ 5, 1, 2, 7],
[ 1, 6, 5, 6],
[ 0, 6, 3, 9],
[17, 14, 12, 10],
[16, 19, 17, 16],
[15, 12, 11, 10]]
a6 = np.hstack((a1, a4)) # 横着连接
print(a6)
>>输出结果:
[[ 5 1 2 7 17 14 12 10]
[ 1 6 5 6 16 19 17 16]
[ 0 6 3 9 15 12 11 10]]
6.2 切分
与级联类似,三个函数完成切分工作:
- np.split
- np.vsplit
- np.hsplit
arr = np.random.randint(0, 100, size=(6,5))
print(arr)
>>输出结果:
[[57, 7, 51, 55, 95],
[82, 3, 80, 14, 40],
[ 8, 29, 4, 69, 79],
[62, 21, 92, 21, 69],
[53, 71, 87, 26, 87],
[34, 32, 7, 35, 40]]
# indices_or_sections=整数:会按照指定的轴向,讲数组切分成N等分, 要求切分的方向上的长度能被N整除
a1, a2 = np.split(arr, indices_or_sections=2, axis=0)
print(a1,a2)
>>输出结果:
[[57 7 51 55 95]
[82 3 80 14 40]
[ 8 29 4 69 79]]
[[62 21 92 21 69]
[53 71 87 26 87]
[34 32 7 35 40]]
# indices_or_sections=[m,n]:按照0:m, m:n, n:的切片逻辑对数组进行拆分 【左闭右开区间】
a3,a4, a5 = np.split(arr, indices_or_sections=[2,3], axis=1)
print(a3,a4,a5)
>>输出结果:
[[57 7]
[82 3]
[ 8 29]
[62 21]
[53 71]
[34 32]]
[[51]
[80]
[ 4]
[92]
[87]
[ 7]]
[[55 95]
[14 40]
[69 79]
[21 69]
[26 87]
[35 40]]
np.vsplit(arr, indices_or_sections=2) # 纵向切分
np.hsplit(arr, indices_or_sections=[2,3]) # 横向切分
练习题
-
生成两个形状分别为(4,4)和(8,4)的二维整型数组,尝试级联
a1 = np.random.randint(0, 10, size=(4,4)) a2 = np.random.randint(0, 10, size=(8,4)) arr = np.vstack((a1, a2)) >>输出结果: [[5 2 6 2] [3 6 8 5] [9 5 3 6] [6 8 7 6] [9 7 8 6] [9 4 8 3] [9 6 8 1] [4 5 8 3] [0 9 6 3] [0 3 1 5] [8 3 3 4] [6 1 2 0]]
-
使用两种方法将上题级联的结果保存并拆分成3等份
a1,a2,a3 = np.split(arr, indices_or_sections=3) >>输出结果: [[5 2 6 2] [3 6 8 5] [9 5 3 6] [6 8 7 6]] [[9 7 8 6] [9 4 8 3] [9 6 8 1] [4 5 8 3]] [[0 9 6 3] [0 3 1 5] [8 3 3 4] [6 1 2 0]]
-
生成一个长度为5的一维整型数组,将类型修改为float32
data = np.random.randint(0, 10, size=5) data.astype(np.float32)
7. ndarray的运算
7.1 基本运算原则:两个矩阵运算,就是对应位置的数据的运算
arr1 = np.random.random(10)
arr2 = np.random.randint(0,10,size=10)
print(arr1,arr2)
>>输出结果:
[0.75169471 0.71153601 0.78249396 0.47342718 0.16683411 0.86732693 0.88897535 0.98752067 0.06502288 0.44564209]
[6 9 8 6 7 0 7 8 8 5]
arr3 = arr1 + arr2
print(arr3)
>>输出结果:
[6.75169471 9.71153601 8.78249396 6.47342718 7.16683411 0.86732693 7.88897535 8.98752067 8.06502288 5.44564209]
# 除了加法,其他运算如:减、乘、除、赋值、位运算等均符合该原则
7.2 广播 Broadcast
ndarray 广播机制的两条规则
- 两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符
- 或其中的一方的长度为1
则认为它们是广播兼容的。 广播会在缺失和(或)长度为1的维度上进行。
a = np.ones((2,3))
b = np.arange(3)
print(a,b)
>>输出结果:
[[1., 1., 1.],
[1., 1., 1.]]
[0, 1, 2]
c = a + b
print(c)
>>输出结果:
[[1., 2., 3.],
[1., 2., 3.]]
a = np.ones((4,3,2))
b = np.random.randint(0, 10, size=(3,2))
print(a,b)
>>输出结果:
[[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]]
[[7, 2],
[3, 4],
[3, 1]]
c = a + b
print(c)
>>输出结果:
[[[8., 3.],
[4., 5.],
[4., 2.]],
[[8., 3.],
[4., 5.],
[4., 2.]],
[[8., 3.],
[4., 5.],
[4., 2.]],
[[8., 3.],
[4., 5.],
[4., 2.]]]
a = np.arange(3).reshape((3,1))
b = np.arange(3)
print(a,b)
>>输出结果:
[[0],
[1],
[2]]
[0, 1, 2]
c = a + b
print(c)
>>输出结果:
[[0, 1, 2],
[1, 2, 3],
[2, 3, 4]]
# ndarray可以跟任意的整数进行广播运算
d = c + 1
print(d)
>>输出结果:
[[1, 2, 3],
[2, 3, 4],
[3, 4, 5]]
练习题
-
a = np.ones((4, 1)), b = np.arange(4), 求a+b
a = np.ones((4, 1)) b = np.arange(4) print(a + b) >>输出结果: [[1. 2. 3. 4.] [1. 2. 3. 4.] [1. 2. 3. 4.] [1. 2. 3. 4.]]
-
假设我们有100个员工考勤需要处理,由于上个月统一调休,所以需要将所有人的总考勤天数-1,如何操作?
data = np.random.randint(20, 23, size=100) print(data - 1) >>输出结果: [21 20 20 19 20 20 20 21 19 21 21 20 20 21 21 19 19 21 19 20 20 20 20 21 19 20 20 21 19 20 21 19 21 20 19 20 21 20 19 19 19 21 19 19 20 19 19 19 20 20 20 19 21 21 19 19 20 20 21 20 19 19 21 19 20 19 20 21 19 20 20 19 19 21 19 21 19 21 19 21 19 21 20 19 21 19 19 20 21 19 19 21 21 20 20 21 21 21 20 19]
-
假设员工上班时间表通过np.random.randint(7,10,100)获取,如何快速找到上班时间不足8小时的员工?
data = np.random.randint(7, 10, size=100) print(data < 8) >>输出结果: [False False False False False True False False False False False False False False False False False False True False True True False False True False False False True False False True False True True True True False False False False False True True True False False True False False False False False True False False True False True True False False False True True True True False False False False True True False False False True False False False True False False False False False False True True True False False False False False False True True False False]
8. ndarray的聚合操作
8.1 求和 np.sum
data = np.random.randint(0, 100, size=5)
print(data)
>>输出结果:
[4, 58, 36, 90, 24]
print(data.sum())
>>输出结果:
212
data = np.random.randint(0, 10, size=(3,2))
print(data)
>>输出结果:
[[0, 7],
[8, 0],
[1, 6]]
print(data.sum())
>>输出结果:
22
# 求每一行的和
print(data.sum(axis=0))
>>输出结果:
[9 13]
# 求每一列的和
print(data.sum(axis=1))
>>输出结果:
[7 8 7]
空值 np.nan
print(type(None))
>>输出结果:
NoneType
print(type(np.nan))
>>输出结果:
float
print(np.nan - 1)
>>输出结果:
nan
np.sum 和 np.nansum 的区别
data = np.array([9., nan, 8., 1., 5., 3., 6., 8., 0., 4.], dtype=float32)
data.sum()
>>输出结果:
nan
np.nansum(data)
>>输出结果:
44.0
8.2 最大最小值np.max/ np.min
arr = np.random.randint(0,10)
print(arr)
>>输出结果:
[6 4 6 6 1 2 4 7 6 3]
print(arr.max(), arr.min())
>输出结果:
7 1
8.3 any() 和 all()
data = np.random.randint(0, 2, size=10).astype(np.bool)
print(data)
>>输出结果:
[False, True, True, True, True, True, False, True, False, True]
# any 一个数组中,如果至少存在一个True, any函数就返回True
data.any()
>>输出结果:
True
# all 一个数组中,如果全都是True, all函数就返回True
data.all()
>>输出结果:
False
8.4 其他常用聚合函数
Function Name NaN-safe Version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true
练习题
-
生成一个Python成绩列表,假设有100人,满分100分,及格60分,如何计算班级的及格率?
data = np.random.randint(0,100,size=100) result = ((data > 60) * 1).mean() print(result) >>输出结果: 0.46
-
标准化就是将一组数据进行如下规则的转换: 减去期望值再除以样本方差,请封装一个函数来实现
def standard_tranform(x): return (x - x.mean())/x.std()
-
随机生成一个一维数组,比较其中是否有至少一个数据大于3倍平均值
data = np.random.randn(100) result = any( data > data.mean()*3 ) print(result) >>输出结果: True
-
生成1000行3列的一个标准正太分布数组,查询每一列是否存在至少一个数据大于该列的3倍标准差
data = np.random.randn(1000, 3) result = (data > data.std(axis=0)*3).any(axis=0) print(result) >>输出结果: [True True True]
-
如何检查两个形状相同的数组数值是完全一致的?
a = np.ones(shape=(4,4)) b = np.ones(shape=(4,4)) result = (a == b).all() >>输出结果: True
四、ndarray进阶
4.1 ndarray数组操作
4.1.1 numpy.append 添加元素
numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中.
注意:
- 插入的维度要保证所有数组的长度是相同的
- 如果没有指定轴,数组会被扁平处理
arr1 = np.array([1,2,3,4])
arr2 = np.append(arr1, 8)
print(arr2)
>>输出结果:
[1, 2, 3, 4, 5, 8]
arr3 = np.random.randint(0, 10, size=(4,3))
arr4 = np.append(arr2, [[1,2,3]], axis=0)
print(arr4)
>>输出结果:
[[4 1 8]
[5 5 4]
[6 0 0]
[1 7 5]
[1 2 3]]
arr5 = np.ones(shape=(4,1))
arr6 = np.append(arr3, arr5, axis=1)
print(arr6)
>>输出结果:
[[4. 1. 8. 1.]
[5. 5. 4. 1.]
[6. 0. 0. 1.]
[1. 7. 5. 1.]]
4.1.2 插入元素 numpy.insert
numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。如果未提供轴,则输入数组会被展开。
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.insert(arr1, 2, 100)
print(arr2)
>>输出结果:
[1, 2, 100, 3, 4, 5]
arr3 = np.array([[7, 3, 5],
[0, 6, 3],
[2, 2, 4],
[0, 1, 1]])
arr4 = np.insert(arr2, 2, [1,1,1], axis=0)
print(arr4)
>>输出结果:
[[7, 3, 5],
[0, 6, 3],
[1, 1, 1],
[2, 2, 4],
[0, 1, 1]]
4.1.3 删除元素 numpy.delete
numpy.delete 函数返回从输入数组中删除指定子数组的新数组。如果未提供轴参数,则输入数组将展开。
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.delete(arr, 1)
print(arr2)
>>输出结果:
[1, 3, 4, 5]
arr3 = np.array([[7, 3, 5],
[0, 6, 3],
[2, 2, 4],
[0, 1, 1]])
arr4 = np.delete(arr, 1,axis=0)
print(arr4)
>>输出结果:
[[7, 3, 5],
[2, 2, 4],
[0, 1, 1]]
4.1.4 数组变形reshape
numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr, newshape, order=‘C’)
- arr:要修改形状的数组。
- newshape:整数或者整数数组,新的形状应当兼容原有形状。
- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
arr1 = np.random.randint(0, 10, size=8)
print(arr1)
>>输出结果:
[8 0 5 3 8 2 5 4]
arr2 = arr1.reshape((2,4), order='C')
print(arr2)
>>输出结果:
[[8 0 5 3]
[8 2 5 4]]
arr3 = arr1.reshape((2, 4),order='F')
print(arr3)
>>输出结果:
[[8 5 8 5]
[0 3 2 4]]
4.1.5 数组迭代器 numpy.ndarray.flat
arr2 = np.random.randint(0, 10, size=(4, 3))
print(arr2)
>>输出结果:
[[8 2 2]
[3 5 7]
[2 6 1]
[2 8 3]]
for i in arr2.flat:
print(i)
>>输出结果:
8
2
2
3
5
7
2
6
1
2
8
3
4.1.6 数组扁平处理
numpy.ndarray.flatten() 返回一份展开的数组拷贝,对拷贝所做的修改不会影响原始数组。
numpy.ravel() 展平的数组元素,返回一个展开的数组引用,修改会影响原始数组。
arr2 = np.random.randint(0, 10, size=(4, 3))
print(arr2)
>>输出结果:
[[7, 3, 5],
[0, 6, 3],
[2, 2, 4],
[0, 1, 1]]
arr2.flatten()
>>输出结果:
[7, 3, 5, 0, 6, 3, 2, 2, 4, 0, 1, 1]
arr2.ravel()
>>输出结果:
[7, 3, 5, 0, 6, 3, 2, 2, 4, 0, 1, 1]
4.1.7 数组翻转 numpy.transpose
numpy.transpose 对换数组的维度
arr2 = np.random.randint(0, 10, size=(4, 3))
print(arr2)
>>输出结果:
[[7, 3, 5],
[0, 6, 3],
[2, 2, 4],
[0, 1, 1]]
arr3 = arr2.transpose()
print(arr3)
>>输出结果:
[[7, 0, 2, 0],
[3, 6, 2, 1],
[5, 3, 4, 1]]
4.2 Numpy 数学函数
4.2.1 三角函数 np.sin(), np.cos(), np.tan()
注意:接收的参数是弧度,不是角度。
# 生成一个取值范围在 -pi ~ pi 之间的数组
data = np.random.random(size=10)*2*np.pi - np.pi
print(data)
>>输出结果:
[0.69514327 -0.70004729 -1.92726858 -0.29962784 -0.87018431 3.0668159 -2.82439672 0.08265095 -0.28990351 2.09689626]
result = np.sin(data)
print(result)
>>输出结果:
[0.64049547 -0.64425385 -0.93713373 -0.29516465 -0.76444777 0.07470709 -0.31190361 0.08255688 -0.28585976 0.86477212]
4.2.2 舍入函数 numpy.around(a, decimals)
- a: 数组
- decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
data = np.random.random(size=10)
print(data)
>>输出结果:
[0.8671543 0.1282897 0.01055623 0.86178051 0.08716256 0.05566391 0.71370066 0.08118095 0.57412796 0.40936495]
result = np.around(data, 3)
print(result)
>>输出结果:
[0.867 0.128 0.011 0.862 0.087 0.056 0.714 0.081 0.574 0.409]
4.2.3 算数函数
加减乘除:add(),subtract(),multiply() 和 divide()
求余运算:numpy.mode()
自然底数的对数:np.log() ,如:np.log2(), np.log10()
a1 = np.random.randint(0, 10, size=(5,3))
b1 = np.random.randint(0, 10, size=3)
np.add(a1, b1)
data = np.random.randint(0, 10, size=5)
np.power(data, 2)
np.mod(data, 2)
np.log10(data)
4.3 Numpy 查找和排序
4.3.1 查找索引 numpy.argmax() 和 numpy.argmin()
data = np.random.randint(0, 100, size=10)
print(data)
>>输出结果:
[19, 60, 28, 48, 81, 39, 87, 62, 61, 19]
print(data.argmax())
>>输出结果:
6
print(data.argmin())
>>输出结果:
0
4.3.2 条件查找 numpy.where()
函数返回输入数组中满足给定条件的元素的索引
data = np.random.randint(0, 100, size=10)
print(data)
>>输出结果:
[19, 60, 28, 48, 81, 39, 87, 62, 61, 19]
condition = data > 60
result = np.where(condition)
print(result)
>>输出结果:
(array([4, 6, 7, 8], dtype=int64),)
4.3.3 快速排序 np.sort() 和 ndarray.sort()
np.sort() 与 ndarray.sort() 区别:
- np.sort() :返回传入数组的排序副本,不改变传入的数组本身
- ndarray.sort() :本地处理,不占用空间,但改变传入的数组
data = np.random.randint(0, 100, size=10)
print(data)
>>输出结果:
[19, 60, 28, 48, 81, 39, 87, 62, 61, 19]
result = np.sort(data)
print(result)
>>输出结果:
[19, 19, 28, 39, 48, 60, 61, 62, 81, 87]
data.sort()
print(data)
>>输出结果:
[19, 19, 28, 39, 48, 60, 61, 62, 81, 87]
4.3.4 索引排序 numpy.argsort()
返回的是数组值从小到大的索引值
data = np.random.randint(0, 10, size=5)
print(data)
>>输出结果:
[9 7 6 1 3]
result = np.argsort(data)
print(result)
>>输出结果:
[3 4 2 1 0]
4.3.5 部分排序 np.partition(a,k)
- 当k为正时,我们想要得到最小的k个数
- 当k为负时,我们想要得到最大的k个数
data = np.random.permutation(10000)
print(data)
>>输出结果:
[7261, 3486, 5101, ..., 6822, 2481, 6462]
result1 = np.partition(data, -2)[-2:]
print(result1)
>>输出结果:
[9998, 9999]
result2 = np.partition(data, 2)[:2]
print(result2)
>>输出结果:
[0, 1]