Numpy是python中非常常用的一个库,所有在该库下定义的数据是以array([])的形式输出,支持简单的对应元素(元素级)的算术运算;最简单的例子就是:如果直接将两个list相加,得到的是这两个list的拼接,而不是元素级别的加法运算;但是numpy中的ndarray却可以做到。
#1.在该数组结狗下,大小相等的数组之间的任何算术运算都会将运算应用到元素级上,这将成为ndarray这一数组结构的一大优点。
import numpy as np
data=np.array([[1,2,3,4],[5,6,7,8]])
d1=data*10 #numpy中的ndarray可以直接进行*10来使得数组中每个元素乘以10;也可以直接进行其他加减乘除运算;区别于列表就不可以这样进行运算
d2=data+data
print(data)
print(d1)
print(d2)
print(data.dtype) #输出该数组的类型dtype;下面为输出该数组的shape,
print(data.shape)
print(data.ndim) ##ndim为该数组的维度信息。
out:
[[1 2 3 4]
[5 6 7 8]]
[[10 20 30 40]
[50 60 70 80]]
[[ 2 4 6 8]
[10 12 14 16]]
int32
(2, 4)
2
#2.ndarray数组的创建,np.array()接受一切序列信息的输入,例如接受一个列表后,产生新的数组结构,就可以进行对应数组的对应元素的加减乘除运算。
data1=[5,4,3,2,1]
arr1=np.array(data1)
data2=[[1,2,3,5],[9,7,6,5]]
arr2=np.array(data2)
print(arr1)
print(arr1.dtype)
print(arr1.shape)
print(arr1.ndim)
print(arr2)
print(arr2.dtype)
print(arr2.shape)
print(arr2.ndim)
out:
[5 4 3 2 1]
int32
(5,)
1
[[1 2 3 5]
[9 7 6 5]]
int32
(2, 4)
2
除了以上的方法可以创建ndarray数组,还有以下方法也可以创建ndarrray数据结构
np.zeros(10) #1
out:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((3,6)) #2
out:
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
np.empty((2,3,4)) ###3 并不像我们想象的那样返回空数组,而是返回一些未初始化的垃圾值,所以尽量少用np.empty(())
np.ones(12) #4
out:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.arange(5) #5
out:
array([0, 1, 2, 3, 4])
np.array(5) #6
out:
array(5)
np.eye((3)) #7
out:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.identity(5) #8
out:
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
np.arange(0) #9生成空列表
out:
array([], dtype=int32)
np.zeros_like([2,3,45,2]) #生成一个与后面同维度的零数组
out:
array([0, 0, 0, 0])
np.ones_like([[1,2,34,4],[3,4,5,6]]) #生成一个与后面同维度的全1数组
out:
array([[1, 1, 1, 1],
[1, 1, 1, 1]])
#3.数组的类型生成与转换
#3.1在创建数组时,可以定义该数组的类型。
arr3=np.array([1,2,3,5],dtype=np.float64)
print(arr3)
#3.2利用ndarray的astype函数转换当前数组的dtype
arr3.astype(np.int64)
#3.3还可将字符串数组转换为数形式
arr4=np.array(['1.23','3.45','6.56','-75.65'],dtype=np.string_)
print(arr4)
print(arr4.dtype)
print(arr4.shape)
print(arr4.ndim)
out:
[b'1.23' b'3.45' b'6.56' b'-75.65']
|S6
(4,)
1
arr5=arr4.astype(float)
print(arr5)
print(arr5.dtype)
print(arr5.shape)
print(arr5.ndim)
out:
[ 1.23 3.45 6.56 -75.65]
float64
(4,)
1
#4.基本索引和切片
arr6=np.arange(10)
print(arr6)
out:
[0 1 2 3 4 5 6 7 8 9]
#4.1 索引
arr6[5] #索引
out:
5
#4.2切片
arr6[5:9]
out:
array([5, 6, 7, 8])
#4.3 索引之后改变值
arr6[5:8]=23
print(arr6)
out:
[ 0 1 2 3 4 23 23 23 8 9]
#4.4 切片之后改变值
arr6[5:8][1]=86 ###切片后得到的索引为1的位置上的值发生改变;在对其值进行重新赋值时i,可以是标量,也可以是数组
print(arr6)
out:
[ 0 1 2 3 4 23 86 23 8 9]
#4.5
arr7=np.array([[1,54,6,75],[23,54,75,87],[87,75,976,43]])
print(arr7)
print(arr7.dtype)
print(arr7.shape)
print(arr7.ndim)
out:
[[ 1 54 6 75]
[ 23 54 75 87]
[ 87 75 976 43]]
int32
(3, 4)
2
arr7[2] ###一个索引即展现了以第一个维度为基准的对应索引位置上的值(该处本身为一个3*4的数组,所以索引为2的即是最后一个维度上的值)
out:
array([ 87, 75, 976, 43])
arr7[2][2] ##索引为2*2位置上的数值
out:
976
arr7[2]=1
print(arr7)
out:
[[ 1 54 6 75]
[23 54 75 87]
[ 1 1 1 1]]
arr7[2]=arr5
print(arr7) ###为了保证数据类型一致,在此处将arr5的数组类型先进行转换。
out:
[[ 1 54 6 75]
[ 23 54 75 87]
[ 1 3 6 -75]]
#5.二维数组
###二维数组 size=4*3
arr2d=np.array([[1,2,3],[4,5,7],[4,5,8],[9,7,8]])
print(arr2d)
out:
[[1 2 3]
[4 5 7]
[4 5 8]
[9 7 8]]
arr2d[3]
out:
array([9, 7, 8])
arr2d[0][2] #arr2d[0,2]一样的效果
out:
3
arr2d[:1]#第一行
out:
array([[1, 2, 3]])
arr2d[:2,1:]
out:
array([[2, 3],
[5, 7]])
#5.1三维数组的索引
arr3d=np.array([[[1,23,4,3,64],[87,64,75,86]],[[99,98,97,96],[9,65,73,54,88]]])
print(arr3d)
out:
[[list([1, 23, 4, 3, 64]) list([87, 64, 75, 86])]
[list([99, 98, 97, 96]) list([9, 65, 73, 54, 88])]]
#6.布尔型索引
names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
print(names)
data=np.random.randn(7,4)
print(data)
out:
['Bob' 'Joe' 'Will' 'Bob' 'Will' 'Joe' 'Joe']
[[-0.54600343 -0.26379891 0.34533487 -1.09481855]
[-1.74235175 -1.35244202 0.48465794 1.48685084]
[-1.13461713 0.00391803 -0.91204128 -0.38060011]
[-0.38104767 -0.05677781 1.38530601 1.59320804]
[ 1.05573431 -0.34345097 0.52701021 1.26982514]
[ 0.57250829 -0.1180959 0.10456965 1.66765285]
[ 0.35410019 1.74913487 0.27306436 -1.05855726]]
names=='Bob' ##结果为一个布尔型数据
out:
array([ True, False, False, True, False, False, False])
data[names=='Bob'] #在此:布尔型数组的长度必须跟被索引的轴长度一致
out:
array([[-0.54600343, -0.26379891, 0.34533487, -1.09481855],
[-0.38104767, -0.05677781, 1.38530601, 1.59320804]])
data[names=='Bob',2:]
out:
array([[ 0.34533487, -1.09481855],
[ 1.38530601, 1.59320804]])
data[names=='Bob',3]
out:
array([-1.09481855, 1.59320804])
names!='Bob'
out:
array([False, True, True, False, True, True, True])
data[names!='Bob']
out:
array([[-1.74235175, -1.35244202, 0.48465794, 1.48685084],
[-1.13461713, 0.00391803, -0.91204128, -0.38060011],
[ 1.05573431, -0.34345097, 0.52701021, 1.26982514],
[ 0.57250829, -0.1180959 , 0.10456965, 1.66765285],
[ 0.35410019, 1.74913487, 0.27306436, -1.05855726]])
data[names!='Bob',3] ##上面的所有行,但是只取第三列
out:
array([ 1.48685084, -0.38060011, 1.26982514, 1.66765285, -1.05855726])
data[data<0]=0 #将data中所有小于0的元素替换成0
print(data)
out:
[[0. 0. 0.34533487 0. ]
[0. 0. 0.48465794 1.48685084]
[0. 0.00391803 0. 0. ]
[0. 0. 1.38530601 1.59320804]
[1.05573431 0. 0.52701021 1.26982514]
[0.57250829 0. 0.10456965 1.66765285]
[0.35410019 1.74913487 0.27306436 0. ]]
data[names!='Joe']=7 #设置整行或者整列数进行替换
print(data)
out:
[[7. 7. 7. 7. ]
[0. 0. 0.48465794 1.48685084]
[7. 7. 7. 7. ]
[7. 7. 7. 7. ]
[7. 7. 7. 7. ]
[0.57250829 0. 0.10456965 1.66765285]
[0.35410019 1.74913487 0.27306436 0. ]]
#8.花式索引
arr8=np.empty((8,4))
for i in range(8):
arr8[i]=i
print(arr8)
out:
[[0. 0. 0. 0.]
[1. 1. 1. 1.]
[2. 2. 2. 2.]
[3. 3. 3. 3.]
[4. 4. 4. 4.]
[5. 5. 5. 5.]
[6. 6. 6. 6.]
[7. 7. 7. 7.]]
#为了以特定顺序选取行子集,只需要传入一个用于指定顺序的整数列表或ndarray即可
arr8[[4,3,7,1]]
out:
array([[4., 4., 4., 4.],
[3., 3., 3., 3.],
[7., 7., 7., 7.],
[1., 1., 1., 1.]])
#也可以从负数开始进行制定 选取顺序 但是注意正索引是从0开始,而负索引是从-1开始的
arr8[[-4,-3,-7,-1]]
out:
array([[4., 4., 4., 4.],
[5., 5., 5., 5.],
[1., 1., 1., 1.],
[7., 7., 7., 7.]])
##在numpy中还可将其进行reshape
arr9=np.arange(32).reshape((4,8))
print(arr9)
out:
[[ 0 1 2 3 4 5 6 7]
[ 8 9 10 11 12 13 14 15]
[16 17 18 19 20 21 22 23]
[24 25 26 27 28 29 30 31]]
arr9[[1,2,2,0],[4,5,6,7]] ##选出的是(1,4),(2,5),(2,6),(0,7)位上的元素
out:
array([12, 21, 22, 7])
#可以利用 np.ix_函数,将两个一维整数数组转换为一个用于选取方形区域的索引器
arr10=np.arange(32).reshape((8,4))
print(arr10)
arr10[np.ix_([1,5,7,2],[0,3,1,2])]
out:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]
array([[ 4, 7, 5, 6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])
#9.数组转置
#数组转置
arr11=np.arange(15).reshape((3,5))
print(arr11)
print(arr11.T)
out:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
##数组的转置经常在dot运算中使用
a=np.dot(arr11,arr11.T)
print(a)
out:
[[ 30 80 130]
[ 80 255 430]
[130 430 730]]
#9.1轴对换 法一:transpose(())需要得到一个由编号组成的元组才能对这些轴进行转置
arr12=np.arange(16).reshape((2,2,4))
print(arr12)
arr12.transpose((1,0,2))
out:
[[[ 0 1 2 3]
[ 4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]]
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
#轴对换 法二:可以利用swapaxees方法,其接受一对编号
arr12.swapaxes(1,2)
out:
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
#10进行数据处理
#接下来讲解利用数组进行数据处理
points=np.arange(-5,5,0.01)
xs,ys=np.meshgrid(points,points)
ys
out:
array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ],
[-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],
[-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],
...,
[ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97],
[ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98],
[ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])
import matplotlib.pyplot as plt
z=np.sqrt(xs**2+ys**2)
z
plt.imshow(z,cmap=plt.cm.gray);plt.colorbar() ##可视化
plt.title("Image plot of $\aqrt{x^2+y^2}$ for a grid of values") ##加标题
#11条件逻辑表达式表述为数组运算
#以下的例子是讲解 讲条件逻辑表达式表述为数组运算
xarr=np.array([1.1,1.2,1.3,1.4,1.5])
yarr=np.array([2.1,2.2,2.3,2.4,2.5])
cond=np.array([True,False,True,True,False])
np.where(cond,xarr,yarr) ###np.where(c,x,y):x if c else y x,y并不一定需要均是数组
out:
array([1.1, 2.2, 1.3, 1.4, 2.5])
##以下例子是随机生成一个4*4的矩阵,然后将其中正数换成2,负数换成-2
arr=np.random.randn(4,4)
print(arr)
np.where(arr>0,2,-2)
out:
[[-0.1969739 0.33814658 0.16296309 1.00751123]
[-0.72757176 0.17708917 -0.23679332 -0.00286326]
[ 0.48326312 0.40867973 0.81624441 0.71301735]
[ 0.7372588 0.87141331 0.27670061 0.4479459 ]]
array([[-2, 2, 2, 2],
[-2, 2, -2, -2],
[ 2, 2, 2, 2],
[ 2, 2, 2, 2]])
np.where(arr>0,2,arr) ##只改变正数,负数按照原数返回
out:
array([[-0.1969739 , 2. , 2. , 2. ],
[-0.72757176, 2. , -0.23679332, -0.00286326],
[ 2. , 2. , 2. , 2. ],
[ 2. , 2. , 2. , 2. ]])
#12数学统计方法(量)
##下面是数学统计方法
b=np.random.randn(5,4)
print(b)
out:
[[-1.02688047 -0.3040927 0.0689912 0.23566393]
[ 1.19643517 0.40972181 -1.20064694 1.46377671]
[ 0.60309008 -0.70278132 1.47046658 0.662415 ]
[-1.20902954 0.80353733 1.09231089 0.39705776]
[ 2.3000793 -1.14322239 0.68485325 -0.79847725]]
b.mean()#平均数
out:
0.2501634187091543
b.sum()
out:
5.003268374183087
b.sum(axis=1) #行和 #b.sum(axis=0) #列和
out:
array([-1.02631804, 1.86928675, 2.03319033, 1.08387643, 1.0432329 ])
#12.2
c=np.array([[0,1,2],[3,4,5],[6,7,8]])
print(c)
out:
[[0 1 2]
[3 4 5]
[6 7 8]]
c.cumsum(axis=1)#按照列计算累积和 ##axis=1 表示的是行(横轴);axis=0 表示的是列(纵轴)
out:
array([[ 0, 1, 3],
[ 3, 7, 12],
[ 6, 13, 21]], dtype=int32)
c.cumprod(axis=1) #按列进行累计积
out:
array([[ 0, 0, 0],
[ 3, 12, 60],
[ 6, 42, 336]], dtype=int32)
#13.布尔数组分类
#下面是用于 布尔数组分方法
arr=np.random.randn(100)
(arr>0).sum() ###上面生成的随机数组中所有正值的和
out:54
bools=np.array([False,False,True,False])
bools.any()
#bools.all() 如果在该基础上进行run命令,得到的是False,因为bools.any()的结果False; 即如果有多个运行结果,则最后的输出结果会将前面的进行覆盖。
out:True
bools.all()
out:False
#14.排序
#下面是排序(针对一维数组和二维数组进行从小到大的排序)
#一维数组的排序
arr=np.random.randn(10)
arr.sort() ###刚开始时没有用print()命令,运行时没有结果。 是因为我们没有显示结果,仅只是排序了。
print(arr)
out:
[-2.10621923 -1.88555307 -1.49008 -0.33242806 -0.11285683 -0.03621601
0.28047066 0.68433259 0.74390029 1.68188086]
arr15=np.random.randn(5,3)
arr15.sort(axis=1) #或者直接arr15.sort(1)也可以得到同样的情况
print(arr15)
out:
[[-1.82842243 -0.37863638 -0.32185094]
[ 0.25392365 0.45132112 0.93831296]
[-0.24001774 0.2894485 0.58490771]
[-1.01344263 -0.16182293 1.17125101]
[ 0.15828504 1.01737674 2.67116318]]
#15.唯一化及其他的逻辑集合
下面是唯一化及其他的集合逻辑
names=np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
np.unique(names) #计算数组中的唯一元素,去掉重复的元素;并且在该处的元素类型是Unicode;还有其他相应函数见笔记
out:
array(['Bob', 'Joe', 'Will'], dtype='<U4')
#下面是 将数组以二进制格式保存到磁盘(但是不太提倡用这种方式来读取或者保存文件数据,,应该多练习利用pandas来读取或保存)
arr=np.arange(10)
np.save('some_array',arr) #以文件扩展名(如果没有定义扩展名,有默认值)为.npy,保存该数组
np.load('some_array.npy') #加载该文件,并输出该数组
out:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#除了np.save(),np.load();;还有np.savez()可以将多个数组保存到一个压缩文件夹下
np.savez('array_archive.npz',a=arr15,b=arr)
arch=np.load('array_archive.npz')
arch['b'] ##或者运行arch['a']
out:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#16 常用函数
from numpy.linalg import inv,qr #numpy.linalg的其他常用函数见笔记
x=np.random.randn(5,5)
mat=np.dot(x.T,x) ##mat=x.T.dot(x)
print(mat)
out:
[[ 7.79168457 -0.96206581 1.81958061 -0.98452273 0.49834921]
[-0.96206581 3.8376205 -2.915517 -3.27398511 0.79716592]
[ 1.81958061 -2.915517 6.54534947 1.12030351 0.28917267]
[-0.98452273 -3.27398511 1.12030351 3.71176082 -0.96532969]
[ 0.49834921 0.79716592 0.28917267 -0.96532969 1.49521011]]
inv(mat) #求逆(此处没有粘结果)
np.dot(mat,inv(mat))#mat.dot(inv(mat))
q,r=qr(mat) ##QR分解
print(q)
print(r)
nsteps=1000
draws=np.random.randint(0,2,size=nsteps)
steps=np.where(draws>0,1,-1)
walk=steps.cumsum() ###每步进行累加,这里其实是要么加1,要么减1
print(walk) #没有粘结果
walk.min()
out:
-17
walk.max()
out:
24
(np.abs(walk)>=10).argmax() #np.abs(walk)>=10表示的是距离是否达到或超过10,而这个是得到第一个绝对值超过或者达到10 的索引值
out:
47
致此,学习完了所有关于numpy的基础命令,关于其更深入的学习,以后有机会再写。初次接触这个,若有错误,欢迎指正!