python之 学习Numpy

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的基础命令,关于其更深入的学习,以后有机会再写。初次接触这个,若有错误,欢迎指正!


猜你喜欢

转载自blog.csdn.net/jasminexjf/article/details/80827471