python:numpy数组运算、排序、统计、随机数生成

本文详细介绍了numpy库在Python中的使用,包括利用数组进行数据处理,条件逻辑的数组运算,数学和统计方法,布尔型数组的操作,排序,唯一化及其他集合逻辑,数组的文件输入输出,线性代数,以及随机数生成。重点讨论了各种函数的使用方法和注意事项,如np.where、聚合函数、排序函数、numpy.linalg和numpy.random模块,强调了这些操作对原数组的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要内容

1) 利用数组进行数据处理

2) 将条件逻辑表述为数组运算

3) 数学与统计方法

4) 用于布尔型数组的方法

5) 排序

6) 唯一化以及其他的集合逻辑

7) 用于数组的文件输入输出

8) 线性代数

1) 利用数组进行数据处理

import numpy as np
points = np.arange(-5,5,1)

print points
xs,ys  = np.meshgrid(points,points)

ys
[-5 -4 -3 -2 -1  0  1  2  3  4]

array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4]])
xs
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4]])

2) 将条件逻辑表述维数组运算

np.where()函数是三元表达式:x if condition else y 的矢量化版本,假设,我们有一个布尔数组和两个数组

xarr = np.array([1,2,3,4,5])

yarr = np.array([6,7,8,9,10])

cond = np.array([True,False,True,True,False,])

加入我们想根据cond数组的情况来选取xarr或yarr数组中的值,有两种方法,一种是列表推导式,另外一种是矢量化

##列表推导式
%timeit  result = [(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
The slowest run took 14.83 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.77 µs per loop
result
[1, 7, 3, 4, 10]
##  矢量化
%timeit result = np.where(cond,xarr,yarr)
The slowest run took 13.14 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 827 ns per loop
result
array([ 1,  7,  3,  4, 10])

从上述结果真可以看出,矢量化的计算速度大概是列表计算的三倍,注意返回结果类型的不一致!np.where函数的参数还可以是标量

arr = np.random.randn(4,4)
arr
array([[ 0.81362115, -0.59091357,  0.04834518,  0.31279457],
       [ 0.14034937, -0.495634  , -1.65939013, -0.06717819],
       [ 1.27779012,  1.00333966, -1.89590419,  0.06417592],
       [-0.39706132, -0.55924097,  0.19493047, -2.09199616]])
np.where(arr>0,2,-2)
array([[ 2, -2,  2,  2],
       [ 2, -2, -2, -2],
       [ 2,  2, -2,  2],
       [-2, -2,  2, -2]])
arr
array([[ 0.81362115, -0.59091357,  0.04834518,  0.31279457],
       [ 0.14034937, -0.495634  , -1.65939013, -0.06717819],
       [ 1.27779012,  1.00333966, -1.89590419,  0.06417592],
       [-0.39706132, -0.55924097,  0.19493047, -2.09199616]])

注意,条件逻辑表达式不改变原数组

np.where(arr>0,2,arr)#只在条件为真是做出改变
array([[-1.05581125, -0.33226037,  2.        , -0.35399731],
       [ 2.        , -0.85778503,  2.        , -0.63576095],
       [ 2.        ,  2.        , -0.76836718,  2.        ],
       [-0.04934349, -0.95880935,  2.        , -1.00340544]])

还可以嵌套

cond1 = np.array([True,False,True,True,True,])

np.where(cond & cond1,0,np.where(cond1,1,2))
array([0, 2, 0, 0, 1])

另外,布尔型数据还可以在计算过程中被当做0或1处理

result = 1*(cond - cond1) + 2*(cond+cond1)
C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: DeprecationWarning: numpy boolean subtract, the `-` operator, is deprecated, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
  if __name__ == '__main__':
result
array([2, 0, 2, 2, 3])

3)数学和统计方法

比如sum、mean、std等聚合计算(aggregation,通常叫做约减(reduction)),既可以当做数组的实例方法调用(array.sum()),还可以当做顶级Numpy函数使用sum(array)。

arr = np.ones((4,5))
arr
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
arr.mean()
1.0
np.mean(arr)
1.0
arr.sum()
20.0
arr
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

注意,聚合函数不改变原数组

np.sum(arr)
20.0
arr[:,2] = 2
arr
array([[ 1.,  1.,  2.,  1.,  1.],
       [ 1.,  1.,  2.,  1.,  1.],
       [ 1.,  1.,  2.,  1.,  1.],
       [ 1.,  1.,  2.,  1.,  1.]])
arr.sum(0)#纵轴方向\
13
arr
array([0, 1, 3, 4, 5])
arr.sum(1)#横轴方向
array([ 6.,  6.,  6.,  6.])
arr.cumsum(0)#纵轴方向的累计和,放回新数组
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]])

基本数组统计方法

方法说明
sum对数组中全部或某轴向的元素求和,0长度的数组的sum为0
mean算数平均数,0长度的数组的mean为NaN
std、var标准差、方差,自由度可调(默认为n)
min、max最大和最小
argmin、argmax最大和最小的索引
cumsum、cumprod所有元素的累计和、累计积

4) 用于布尔型数组的方法

1) sum 统计布尔型数组中True的个数,由于布尔型数组中True会被当成1来参加运算。

2) any 用于测试数组中是否存在一个或多个True

3) all 用来检查数组中所有值是否都是True

4) 另外 any、all也可以用与非布尔型数组,所有非0元素会被当做True

import numpy as np

bools = np.array([False,False,True,False,True])

bools.sum()
2
bools.any()
True
bools.all()
False

从上述结果中,any和all说明bools中有True但不全是,而sum统计了True的个数。

5)排序

arr = np.arange(5)

arr[2]=5
arr
array([0, 1, 5, 3, 4])
arr.sort()
arr
array([0, 1, 3, 4, 5])
np.sort(arr)
array([0, 1, 3, 4, 5])
array = np.arange(1,5,0.5).reshape(2,4)
array
array([[ 1. ,  1.5,  2. ,  2.5],
       [ 3. ,  3.5,  4. ,  4.5]])
array[:,1] = np.array([3.5,1.5]).T
array
array([[ 1. ,  3.5,  2. ,  2.5],
       [ 3. ,  1.5,  4. ,  4.5]])
array.sort(0)#在纵轴上排序
array
array([[ 1. ,  1.5,  2. ,  2.5],
       [ 3. ,  3.5,  4. ,  4.5]])
array[:,1] = np.array([3.5,1.5]).T
print array
array.sort(1)#在横轴上排序
array
[[ 1.   3.5  2.   2.5]
 [ 3.   1.5  4.   4.5]]


array([[ 1. ,  2. ,  2.5,  3.5],
       [ 1.5,  3. ,  4. ,  4.5]])

python内置排序程序

array = np.array([1,2,6,3,5,4])

array
array([1, 2, 6, 3, 5, 4])
sorted(array)#python内置一般返回列表
[1, 2, 3, 4, 5, 6]
array#内置不改变原来是数组?
array([1, 2, 6, 3, 5, 4])

注意,sort会在原数组上做修改

6) 唯一化以及其他的集合逻辑

numpy提供一些针对**一维**ndarray的基本集合运算,最常用的是np.unique(),它用于找出数组中的唯一值并返回已排序的结果

names = np.array(['a','b','c','a','c'])
names
array(['a', 'b', 'c', 'a', 'c'], 
      dtype='|S1')
np.unique(names)
array(['a', 'b', 'c'], 
      dtype='|S1')
names
array(['a', 'b', 'c', 'a', 'c'], 
      dtype='|S1')
ints = np.array([3,3,3,2,2,2,1,1,4,4])
ints
array([3, 3, 3, 2, 2, 2, 1, 1, 4, 4])
%timeit 
The slowest run took 42.94 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 3.8 µs per loop
np.unique(ints)
array([1, 2, 3, 4])
#上述代码实现功能可以python来实现
%timeit sorted(set(ints))
The slowest run took 25.40 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.75 µs per loop
sorted(set(ints))
[1, 2, 3, 4]

可以看出并不是所有的内置都是效率低的~

np.in1d用于测试一个数组中的值是否存在于另外一个数组中,并返回一个大小和测试数组一样的布尔型数组

value = np.array([6,0,0,3,2,5])
np.in1d(value,[2,3,6])
array([ True, False, False,  True,  True, False], dtype=bool)

常见的数组集合运算

方法说明
unique(x)计算x中的唯一元素,并返回有序结果
intersect1d(x,y)计算x和y中的公共元素(交集),并返回有序结果
union1d(x,y)计算x和y的并集,并返回有序结果
in1d(x,y)得到一个表示“x中元素是否在y数组中”的布尔型数组
setdiff1d(x,y)集合的差,即元素在x中且不在y中
setxor1d(x,y)集合的对称差(异或),即存在于一个数组中但不同时存在于两个数组中的元素

7) 用于数组的文件输入输出

numpy能够读写磁盘上的文本数据和二进制数据,pandas中有将表格型数据读取到内存的工具

将数组以二进制格式保存到磁盘

np.save和np.load是读写磁盘数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中。

arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.save('E:\python\juputer\sameArray',arr)#可以不加后缀,系统会自动加.npy
np.load('E:\python\juputer\sameArray.npy')#必须有后缀
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

此外,还可以将多个数组保存到一个压缩文件中,将数组以关键字参数的形式传入即可

array = np.array([1,2,0,0,0,0,0])

np.savez('bb',a=arr,b=array)#貌似只能压缩到默认路径下,不知道什么原因
arch = np.load('bb.npz')
arch['b']
array([1, 2, 0, 0, 0, 0, 0])

存取文本数据

从文本中加载说句是一个非常标准的任务。numpy主要有np.loadtxt()和np.genfromtxt()函数,pandas主要有read_csv和read_table()函数。

arr = np.random.randn(4,3)
arr
array([[-0.51108593,  0.72750055, -0.15797328],
       [-0.36643894,  0.55478468,  0.30060344],
       [-0.76537983, -0.28501039, -0.14497014],
       [ 0.72564297, -1.27952004,  0.30936996]])
np.savetxt('test.txt',arr)
arr = np.loadtxt('test.txt')
arr
array([[-0.51108593,  0.72750055, -0.15797328],
       [-0.36643894,  0.55478468,  0.30060344],
       [-0.76537983, -0.28501039, -0.14497014],
       [ 0.72564297, -1.27952004,  0.30936996]])

8)线性代数

线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵等)是任何数组库的重要组成部分。numpy提供了一个用于矩阵乘法的dot函数(数组方法),实现数组的点积。

常用的numpy.linalg函数

函数说明
diag以一维数组的形式放回方阵的对角线(或非对角线元素),或将一维数组换为方阵(非对角线元素为0)
dot矩阵乘法
trace计算对角线元素和
det计算矩阵的行列式
eig计算方阵的特征值和特征向量
inv计算方阵的逆
pinv计算矩阵的Moore-Penrose伪逆
qr计算qr分解
svd计算奇异值(SVD)
solve解线性方程组Ax=b,其中A为一个方阵
lstsq计算Ax=b的最小二乘解
x = np.arange(1,12,2).reshape(2,3)
x
array([[ 1,  3,  5],
       [ 7,  9, 11]])
y = np.arange(2,13,2).reshape(3,2)
y
array([[ 2,  4],
       [ 6,  8],
       [10, 12]])
np.dot(x,y)#等价于x.dot(y)
array([[ 70,  88],
       [178, 232]])
y
array([[ 2,  4],
       [ 6,  8],
       [10, 12]])
x = np.random.randn(5,5)
x
array([[ 1.63103816,  0.71983566,  1.10352515, -0.27938298,  0.11040744],
       [ 0.41088167, -0.73636959,  1.39466507,  0.02659672, -1.20904744],
       [ 0.5186612 , -1.86480014,  2.89604141, -0.63832998, -0.49133989],
       [ 1.63042984,  0.57143769, -1.11857589, -0.02013889,  0.46964764],
       [ 1.23888832,  3.42855521, -2.36622283, -1.22878746,  1.80597763]])
mat = x.T.dot(x)
np.linalg.inv(mat)
array([[ 0.27742733, -0.19565147, -0.16151662,  0.02161428, -0.04933913],
       [-0.19565147,  0.67591051,  0.47450978,  0.64285176, -0.03838762],
       [-0.16151662,  0.47450978,  0.6679418 ,  1.00350966,  0.69607497],
       [ 0.02161428,  0.64285176,  1.00350966,  2.60588578,  1.45256531],
       [-0.04933913, -0.03838762,  0.69607497,  1.45256531,  1.87265356]])
mat.T.dot(np.linalg.inv(mat))
array([[  1.00000000e+00,   1.10290647e-16,   6.50206020e-17,
         -9.56263991e-18,   2.31165248e-16],
       [  1.86021783e-16,   1.00000000e+00,  -4.42906701e-16,
         -2.93319024e-16,  -1.88919268e-15],
       [  4.43545563e-17,   1.16736094e-15,   1.00000000e+00,
          8.64035632e-16,   4.01786135e-16],
       [ -9.10610531e-17,   2.30215482e-16,   2.61428391e-16,
          1.00000000e+00,  -9.26009142e-17],
       [  2.00085966e-16,  -1.58177563e-15,  -1.19547067e-15,
         -1.29203693e-15,   1.00000000e+00]])
s,v,d = np.linalg.svd(mat)
s
array([[-0.16523474,  0.77808826,  0.58918158,  0.13972992, -0.02483462],
       [-0.64883151,  0.20661516, -0.29383095, -0.64803915,  0.17331036],
       [ 0.64914815,  0.49923165, -0.41237116, -0.21362089,  0.33718034],
       [ 0.10505073, -0.30923038,  0.52695933, -0.24319507,  0.74599661],
       [-0.3453783 ,  0.08386396, -0.34466264,  0.67508746,  0.54694172]])
v
array([ 37.27592672,   9.26487289,   1.86483196,   0.86523652,   0.23402418])
d
array([[-0.16523474, -0.64883151,  0.64914815,  0.10505073, -0.3453783 ],
       [ 0.77808826,  0.20661516,  0.49923165, -0.30923038,  0.08386396],
       [ 0.58918158, -0.29383095, -0.41237116,  0.52695933, -0.34466264],
       [ 0.13972992, -0.64803915, -0.21362089, -0.24319507,  0.67508746],
       [-0.02483462,  0.17331036,  0.33718034,  0.74599661,  0.54694172]])

9)随机数生成

numpy.random模块是对python内置random进行补充,增加了一些用于高效生成多种概率分布的样本值的函数,例如,你可以用normal来得到一个标准正态分布的4*4样本数组。

常用的随机数生成函数

函数说明
seed确定随机数生成器的种子
permutation返回一个序列的随机排列或返回一个随机排列的范围
shuffle对一个序列就地随机排列
rand产生均匀分布的样本值
randint从给定的上下限范围内随机选取整数
randn产生正态分布(平均数为0,标准差为1)的样本值,类似于MATLAB接口
binomial产生二项分布的样本值
normal产生正态分布(高斯分布)的样本值
beta产生beta分布的样本值
chisquare产生卡方分布的样本值
gamma产生gamma分布的样本值
uniform产生[0,1)均匀分布的样本值
#产生高斯分布
sample = np.random.normal(size=(4,4))
sample
array([[ 0.89509853, -0.83225074,  1.29474565,  0.45655647],
       [-1.43400126,  1.32985572,  2.30055355,  2.46808663],
       [-2.4563378 , -0.66266506, -1.15600003, -0.60034993],
       [-1.79678809, -0.69896066,  1.02434411,  0.1271823 ]])

总结

1)条件逻辑表达式不改变原数组,会返回新的布尔型数组

2)聚合函数不改变原数组,返回结果值

3)监测和检验函数不改变原数组,返回布尔型数据

4)排序函数能够改变原数组,在原来的数据上修改

5)唯一化及集合逻辑不改变原数组,返回新的数组

6)线性代数、矩阵运算不改变原数组,返回结果数组

7)切片相当于引用,指向同一内存区,因此不管改变原数组,还是新的引用变量都会改变原数组

8) numpy元素级通用函数不改变原数组

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨岚❤️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值