numpy快速处理数据学习笔记

numpy快速处理数据

《python编程基础及应用》 陈波

一、多维数组

补充知识:python的名字绑定机制会使得内存中除了保存真正的数据之外,还要保存同样数量的对象引用,会导致存储空间的浪费

  • numpy中的数组内部元素需要保持一致
  • ndarray 的内部数据是连续组织的
import numpy as np
a = np.array([[1,2,3,4],[4,5,6,7]])  # array 可以将元组、列表或者嵌套元组、嵌套列表转为多维数组
b = np.array((1,2,3,4),dtype=np.float32) # dtype=np.float32 是将该数组的元素的数据类型设置为float32,32代表是32位 4字节
print("a = \n",a)
print("a.shape=",a.shape)  # a.shape = (2,4)  代表的是 2行4列,数据类型是元组类型,第一个元素是0轴 长度为2,第二个元素是1轴 长度为4
print("a.type=",type(a))  #  type 是返回该数组的类型
print("a.dtype=",a.dtype) # dtype 可以返回该数组的元素的数据类型
a = 
 [[1 2 3 4]
 [4 5 6 7]]
a.shape= (2, 4)
a.type= <class 'numpy.ndarray'>
a.dtype= int32
import numpy as np 

a = np.array([[1,2,3,4],[5,6,7,8]])
b = a.reshape(4,2) # 将a的形状改为4行2列,但是a和b是共享内存的(存储位置相同,可以理解为名字绑定问题)
b[0][1] = 9  
print("a=\n",a)
print("b=\n",b) # 最后是a和b 都发生了改变

c = a.astype(np.float32) # 通过astype将数组元素的数据类型进行转换,生成了新的数组
c[0][1] = 2
print("a=\n",a)
print("a=\n",b)
print("c=\n",c)

a=
 [[1 9 3 4]
 [5 6 7 8]]
b=
 [[1 9]
 [3 4]
 [5 6]
 [7 8]]
[[1 9 3 4]
 [5 6 7 8]]
[[1 9]
 [3 4]
 [5 6]
 [7 8]]
[[1. 2. 3. 4.]
 [5. 6. 7. 8.]]

二、数组的快速生成

(一)、等差数列

  • 语法:arange(start,end,步长) 和 range的语法一样,不包含终值
  • 语法:linspace(start,end,个数)
    • linspace默认是包含end,如果endpoint=0是不包含的end(终止值)
  • 注意:linspace中第三个参数表示的是生成元素个数,间接实现步长的功能
import numpy as np
a = np.arange(0,1,0.1)
b = np.linspace(0,1,10,endpoint=0) # endpoint=0 代表的是不包含终值
c = np.linspace(0,1,10)  # 默认包含终值
print("a=",a)
print("不包含终值:b=",b)
print("包含终值:c=",c) 
a= [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
b= [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
c= [0.         0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
 0.66666667 0.77777778 0.88888889 1.        ]

(二)、等比数列

  • 语法:logspace(起始值,终值,个数)
  • 注意:logspace默认是10为基数,可以通过参数base进行修改
  • logspacelinspace一样,默认都是将endpoint=True包含终值
import numpy as np
a = np.logspace(0,2,5,endpoint=0)  
b = np.logspace(0,2,5,base=2) # eg:2的0次方;2的1次方
print("以10为底:",a)
print("以2为底:",b)
以10为底: [ 1.          2.51188643  6.30957344 15.84893192 39.81071706]
以2为底: [1.         1.41421356 2.         2.82842712 4.        ]

(三)、数组生成函数

  • zeros()生成元素全部为0
  • empty()生成指定形状的数组且不对数组进行初始化,但是里面的元素值不确定
  • ones()全部为1
    - full() 将所有元素初始化为指定值
  • eye()identity()生成主对角为1的 eg:eye(3)
  • diag()指定对角线的数据
import numpy as np

print(np.zeros((2,2),np.float32)) # 生成2行2列的浮点型的数组
print(np.empty(2,np.int32)) 
print(np.ones((1,2)))
print(np.full(3,2))  # (3,2) 3代表是形状;2代表的是值,用2来填充
print(np.eye(2))
print(np.diag([1,2,3]))

# 这些函数的第一个参数都是形状,如果是一个,则生成一个一维数组;如果是多个整数的元组,则生成对应的多维数组
[[0. 0.]
 [0. 0.]]
[         0 1072693248]
[[1. 1.]]
[2 2 2]
[[1. 0.]
 [0. 1.]]
[[1 0 0]
 [0 2 0]
 [0 0 3]]

(四)、fromfunction()

案列:生成一个长度为31的一维数组,每一个数组元素代表星期,eg:0代表是星期天

import numpy as np

def weekday(i):
    return (i+6)%7  #  1号为星期六
print(np.fromfunction(weekday,(31,)))  #  float64
print(np.fromfunction(weekday,(31,)).astype(np.int))  # float64转为int
[6. 0. 1. 2. 3. 4. 5. 6. 0. 1. 2. 3. 4. 5. 6. 0. 1. 2. 3. 4. 5. 6. 0. 1.
 2. 3. 4. 5. 6. 0. 1.]
[6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1]

fromfunction(参数1,参数2): 参数1函数名参数2数组的形状,数据类型为元组,默认的数组元素的类型为float64
上述例子中weekday的参数是数组元素的下标为参数,(31,)生成一维数组。
下面是测试:函数名的实参值是不是数组下标

import numpy as np
def i(i):
    return i
print(np.fromfunction(i,(31,)))
[ 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.]

案例2:99乘法表
生成一个9行9列的二维数组

import numpy as np

def multi(i,j):
    return (i+1)*(j+1)
print(np.fromfunction(multi,(9,9)).astype(np.int))
# i,j的参数分别是对应元素的行和列的下标
[[ 1  2  3  4  5  6  7  8  9]
 [ 2  4  6  8 10 12 14 16 18]
 [ 3  6  9 12 15 18 21 24 27]
 [ 4  8 12 16 20 24 28 32 36]
 [ 5 10 15 20 25 30 35 40 45]
 [ 6 12 18 24 30 36 42 48 54]
 [ 7 14 21 28 35 42 49 56 63]
 [ 8 16 24 32 40 48 56 64 72]
 [ 9 18 27 36 45 54 63 72 81]]

三、一维数组存取

1、整数下标及切片——共享内存

import numpy as np
a = np.arange(10)
print("a=\n",a)
print("a[2]= ",a[2])
print("a[1:3]=",a[1:3])
print("a[-1::-1]=",a[-1::-1])
c = a[0:3]  # 切片0到3的数组给c
a[:3] = 3,2,1
print("修改后的a",a)
print("c=",c) 
# 注意:和列表的操作形式一样,但是列表进行切片操作的时候,解释器会复制元素创建型新的列表,而numpy进行数组切片的时候和原数组是共享内存的(原数组或新数组进行修改,二者都会修改)
a=
 [0 1 2 3 4 5 6 7 8 9]
a[2]=  2
a[1:3]= [1 2]
a[-1::-1]= [9 8 7 6 5 4 3 2 1 0]
修改后的a [3 2 1 3 4 5 6 7 8 9]
c= [3 2 1]
  • 注意:索引是取值,切片保留结构
  • 注意:和列表的操作形式一样,但是列表进行切片操作的时候,解释器会复制元素创建型新的列表,而numpy进行数组切片的时候和原数组是共享内存的(原数组或新数组进行修改,二者都会修改),切片所得的数组作为视图。见下述例子
import numpy as np
a = np.arange(10)
c = a[:5]
a[2] = 88
print("c=",c)
print("a=",a)
# 注意:需要保持独立性,可以使用copy
c= [ 0  1 88  3  4]
a= [ 0  1 88  3  4  5  6  7  8  9]

2、整数列表作为下标

通过给数组指定一个整数列表来选择指定下标的元素

  • 好处:新数组与原数组共享存储空间
import numpy as np
a = np.arange(1,13,2)
print("a=\n",a)
x = a[[1,3,5]]  # 1,3,5分别是指a的下标
print("x=",x)
x[0]=13
print(x[[1,2]]) # 获取x下标为1和2的元素
x[[1,2]] = 14,15
print("x=",x)
a1 = a[[3,1,-1,-2]]
print("a1=",a1)
a=
 [ 1  3  5  7  9 11]
x= [ 3  7 11]
[ 7 11]
x= [13 14 15]
a1= [ 7  3 11  9]

注意:a[[3,1,-1,-2]]是获取a中下标为3,1,-1,-2的元素

3、 整数数组作为下标

import numpy as np

a = np.arange(10)  # 【0,1,2,3,】
print(a)
idx = np.array([[1,3,4,7],[3,3,-3,8]])  # 2行4列的数组
print("idx={}".format(idx))
x = a[idx]  # idx中的元素作为了a的下标进行索引
print("x=\n",x)
# idx的形状大小,x也会根据idx的形状大小
[0 1 2 3 4 5 6 7 8 9]
idx=[[ 1  3  4  7]
 [ 3  3 -3  8]]
x=
 [[1 3 4 7]
 [3 3 7 8]]

4、布尔列表或数组作为下标

import numpy as np
a = np.arange(5)
idex1 =[True,False,False,True,False]
print("a=",a)

print(a[idex1])  # 将True对应的下标作为索引进行取值
a= [0 1 2 3 4]
[True, False, False, True, False]
[0 3]

四、多维元素存取

1、整数下标切片

import numpy as np

a = [[ i+j for i in range(5)]for j in range(6)]  # 快速生成5行6列的嵌套列表
arr = np.array(a)
print("arr=\n",arr)
b = arr[1:5,1:3]  # 两个切片结果为二维数组
print("b=",b)
b[1][1] = 6
print("arr=",arr)
print("b=",b)
# 请注意观察arr和b,b发生了修改,arr也发生了修改,说明切片会原数组和新数组有共享内存
arr=
 [[0 1 2 3 4]
 [1 2 3 4 5]
 [2 3 4 5 6]
 [3 4 5 6 7]
 [4 5 6 7 8]
 [5 6 7 8 9]]
b= [[2 3]
 [3 4]
 [4 5]
 [5 6]]
arr= [[0 1 2 3 4]
 [1 2 3 4 5]
 [2 3 6 5 6]
 [3 4 5 6 7]
 [4 5 6 7 8]
 [5 6 7 8 9]]
b= [[2 3]
 [3 6]
 [4 5]
 [5 6]]
  • 二维数组的索引: a[行索引,列索引]
  • a[:,:] 结果是二维数组
  • a[,:] 结果是一维数组
(1)、三种方式访问同一种元素
# 三种方式访问同一个元素
print(arr[1][2])
print(arr[1,2])
idex = (1,2)
print(arr[idex])
3
3
3
(2)、如何获取对应元素在python中标准数据结果 -item()

利用item()获取元素的标准结果

import numpy as np

arr = np.arange(6).reshape(2,3).astype(np.int)
print(arr[1][1],type(arr[1,1]))
print(arr.item(1,1),type(arr.item(1,1)))  # item(元素下标),确定数组的元素的数据类型
4 <class 'numpy.int32'>
4 <class 'int'>
(3)、创建切片下标

补充知识:多维数组中用逗号分隔的下标可以视为一个“元组”

  • slice(起始值,终值,步长) 如果参数忽略,需要用None进行填充
  • slice [slaɪs] 切片
import numpy as np

a = np.arange(15).reshape(3,5)
print("a= \n",a)
idx = slice(0,None,1),slice(1,4,2)  #数据类型为元组           a[0::1,1:4:2]
print("idx=",idx,"数据类型:",type(idx))
b =a[idx]
c = a[0::1,1:4:2]
print(b)
print(c)
a= 
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
idx= (slice(0, None, 1), slice(1, 4, 2)) 数据类型: <class 'tuple'>
[[ 1  3]
 [ 6  8]
 [11 13]]
[[ 1  3]
 [ 6  8]
 [11 13]]

补充知识:np.s_是一个特殊对象,生成切片下标对象 eg:np.s_[::3,2::2] 等于 slice(None,None,3),slice(2,None,2)等于数组名[::3,2::2]

import numpy as np

a = np.arange(10).reshape(5,2)
idx = np.s_[1::,0::]
print("idx的数据类型为:",type(idx))   #<class 'tuple'> 元组
b = a[idx]
b[1][1] = 666
print(a)
print(b)
# 注意:该方法会与原数组和新数组有共享内存
idx的数据类型为: <class 'tuple'>
[[  0   1]
 [  2   3]
 [  4 666]
 [  6   7]
 [  8   9]]
[[  2   3]
 [  4 666]
 [  6   7]
 [  8   9]]

2、整数列表、元组、数组、布尔数组

import numpy as np
a = [[x+y for x in range(5)] for y in range(7)]
a = np.array(a).astype(np.int)
print("元组:a[(1,2,1,3),(0,0,2,1)=",a[(1,2,1,3),(0,0,2,1)]) # 通过元组的对应位置来获取元素eg:[1,0];[2,0];[1,2],[3,1]    [1 2 3 4]
print("列表:a[4:,[0,2,4]]=",a[4:,[0,2,4]])  # 获取4、5行中0、2、4列的元素
select = np.array([0,1,0,1,1,1,0],dtype=np.bool)  # boolean index did not match indexed array along dimension 0; dimension is 7 but corresponding boolean dimension is 6

print("布尔:a[select,1]=",a[select,1])  # 布尔数组的长度要和数组列长度一致
元组:a[(1,2,1,3),(0,0,2,1)= [1 2 3 4]
列表:a[4:,[0,2,4]]= [[ 4  6  8]
 [ 5  7  9]
 [ 6  8 10]]
布尔:a[select,1]= [2 4 5 6]

五、内存结构

了解数组的内存存储结构,便于理解切片和整数数组进行访问原数组与新数组内存的关系。

  • 案列:生成一个3行3列的数据为float32(4字节)的数组,使用数据类型(dtype)、维数(ndim)、形状(shape)、步幅(strides)
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=np.float32)
print("a=\n",a)
print("a.dtype=",a.dtype)  # dtype是数据类型展示
print("type(a.dtype)=",type(a.dtype))
print("a.ndim=",a.ndim)  # ndim代表为维度,2
print("a.shape=",a.shape) 
print("a.data=",a.data) # <memory at 0x0000017F31211480>  数组的内存位置
print("a.strides=",a.strides)# (12,4)
"""
strides 作用是记录每一个轴相邻两个元素的地址差,返回的数据类型为元组,(12,4) 12代表是0轴的相邻两个元素地址差。eg:x行和x+1行,
且列相同的元素之间的地址差 。float32 是4字节,因此一个元素占了4字节,3个元素占3*4(12字节),这是12的由来;
4 代表的是1轴相邻元素的地址差,eg: x列和x+1列,且行相同之间元素的地址差。 一个元素是4字节,应该差了4
"""
a=
 [[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
a.dtype= float32
type(a.dtype)= <class 'numpy.dtype'>
a.ndim= 2
a.shape= (3, 3)
a.data= <memory at 0x0000017F31211480>
a.strides= (12, 4)





'\nstrides 作用是记录每一个轴相邻两个元素的地址差,返回的数据类型为元组,(12,4) 12代表是0轴的相邻两个元素地址差。eg:x行和x+1行,\n且列相同的元素之间的地址差 。float32 是4字节,因此一个元素占了4字节,3个元素占3*4(12字节),这是12的由来;\n4 代表的是1轴相邻元素的地址差,eg: x列和x+1列,且行相同之间元素的地址差。 一个元素是4字节,应该差了4\n'

image-20220314235611106

注意:上面的地址计算公式也是c语言的地址计算公式

  • 元素地址 = 首地址+轴0下标*步幅+轴1下标*轴1的步幅
  • 案列:切片时,为什么原数组和新数组会共享内存
import numpy as np

a = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=np.float32)
b = a[::2,::2]
print("a=\n",a)
print("b=\n",b)
print("a.strides=",a.strides) #(12,4)
print("b.strides=",b.strides) # (24,8)
print("a.data=",a.data)
print("b.data=",b.data)
a=
 [[1. 2. 3.]
 [4. 5. 6.]
 [7. 8. 9.]]
b=
 [[1. 3.]
 [7. 9.]]
a.strides= (12, 4)
b.strides= (24, 8)
a.data= <memory at 0x000001C1DE4F0480>
b.data= <memory at 0x000001C1DE4F0480>

上述案列分析:a形状是3行3列,b形状是2行2列a.strides=(12,4) b.strides=(24,8) 。观察b中元素1和7,a中1和7的位置中相隔一行,正好是12的两倍 24,因此借助strides可以计算出数据的地址位置。注意:布尔类型、数组等进行访问时,strides就无法计算位置,只有复制元素进行操作

六、ufunc函数

ufunc 是universal function的缩写,大多数的ufunc函数时都是通过C语言进行编写的。因为在对多维进行计算的时候需要进行循环,c语言的循环比python的循环效率要高。

1、三角函数

下述代码我们以sin为列,`其他的三角函数(cos、tan、arctan)相似`
#  生产1~10pi 的1000个等差数列,并计算出对应的sin(),在通过matplotlib进行画图
import numpy as np
from matplotlib import pyplot as plt

x = np.linspace(0,10*np.pi,1000)
y = np.sin(x)  #  会生成和x形状一样的数组
print("x.shape=",x.shape,"y.shape=",y.shape)
# 展示10个
print("x[::100]=",x[::100])
print("y[::100]=",y[::100])
plt.plot(x,y)
plt.show()
x.shape= (1000,) y.shape= (1000,)
x[::100]= [ 0.          3.14473739  6.28947478  9.43421217 12.57894956 15.72368695
 18.86842435 22.01316174 25.15789913 28.30263652]
y[::100]= [ 0.         -0.00314473  0.00628943 -0.00943407  0.01257862 -0.01572304
  0.0188673  -0.02201138  0.02515525 -0.02829886]

在这里插入图片描述

sin()函数中还有一个参数是用来指定数据输出保存在那个一个数组中,是通过out

import numpy as np

x = np.linspace(0,10,10)
y = np.zeros(10)
t = np.sin(x,out=y)  # sin()依然也会将数组赋值给t
print("id(x)=",id(x),"id(y)=",id(y))
print("y=",y)
print("t=",t)

# 修改其中一个数组中值,发现是共享内存的 
y[1] = 10
print("y=",y)
print("t=",t)  
id(x)= 1932215179104 id(y)= 1932215354592
y= [ 0.          0.8961922   0.79522006 -0.19056796 -0.96431712 -0.66510151
  0.37415123  0.99709789  0.51060568 -0.54402111]
t= [ 0.          0.8961922   0.79522006 -0.19056796 -0.96431712 -0.66510151
  0.37415123  0.99709789  0.51060568 -0.54402111]
y= [ 0.         10.          0.79522006 -0.19056796 -0.96431712 -0.66510151
  0.37415123  0.99709789  0.51060568 -0.54402111]
t= [ 0.         10.          0.79522006 -0.19056796 -0.96431712 -0.66510151
  0.37415123  0.99709789  0.51060568 -0.54402111]

2、四则运算

image-20220315132142462

image-20220315132216719

import numpy as np

a = np.array([1,3,5],dtype=np.float32)
b = np.array([2,4,6],dtype=np.int)
c1 = np.add(a,b)
c2 = a+b
print("c1=",c1)
print("c2=",c2)
# 注意:由于a是float类型的数据,而b是int类型的数据,因此结果会转换为float
c1= [ 3.  7. 11.]
c2= [ 3.  7. 11.]

3、比较运算与布尔运算

  • 比较运算
    == 、<、>、!=等比较符也适用于数组
import numpy as np

a = np.array([1,2,3])
b = np.array([3,2,1])
print("a<b=",a<b)  # 注意是两个数组中对应下标的元素进行比较
print("a<b=",np.less(a,b))  # 但是建议还是直接使用运算符
a<b= [ True False False]
a<b= [ True False False]
  • 布尔运算
    与(and)、或(or)、非(not)、异或(xor),数组不能直接用and等进行运算,需要使用logical_or()、logical_and()、logical_not()、logical_xor()
import numpy as np

a = np.array([1,2,3])
b = np.array([3,2,1])
print(a>b)
print(a==b)
print("a>b or a==b:",np.logical_or(a>b,a == b)) # a>b or a==b
print("np.all(a>b):",np.all(a>b))  # 只有全部a都大于b的时候,才是True
print("np.any(a>b):",np.any(a>b))  # 当其中只要有一个是a>b的时候,是True
[False False  True]
[False  True False]
a>b or a==b: [False  True  True]

4、自定义构建ufunc函数

当标准的ufunc函数不能满足我们使用的时候,我们可自定义ufunc函数。自定义ufunc函数一样可以作用域数组每一个元素。自定义ufunc函可用c语言、
python(缺点:执行效率低)、c和python交叉

import numpy as np
import math
from matplotlib import pyplot as plt
def signalcomp(x,freq):
    y = math.cos(x)
    y += 0.2*math.cos(freq*x)
    retur
x = np.linspace(0,5*np.pi,1000)
ufunc1 = np.frompyfunc(signalcomp,2,1) # 构建自定义ufunc函数,第二个参数的2表示可以输入2个参数,第三个参数的1表示的是有1个结果返回
y = ufunc1(x,10).astype(np.float32) # 自定ufunc函数最后的结果是返回的object,因此我们需要对它进行数组类型转换
plt.plot(x,y)
plt.show()

​[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlMdlkku-1665395209783)(output_56_0.png)]

7、广播

数组形状相同可以进行运算操作,那么不同形状的数组如何进行操作,通过广播。
image-20220315164435346

import numpy as np

a = np.arange(0,50,10).reshape(-1,1)  # 5行1列的二维数组(通过确定列来确定行)
b = np.arange(0,4)  # 生成长度为4的一维数组
c = a+b
print("a.shape:",a.shape,"b.shape:",b.shape)
print("a=\n",a)
print("b=\n",b)
print("c.shape:",c.shape)
print(" c=\n",c)
"""
c=a+b
1、满足上面广播规则第1条,将b数组转为二维数组(1,4) 1行4列的
2、满足广播规则第2条,输入数组:a是5行1列;b是1行4列  结果输出:为5行4列
3、满足广播规则第4条,c[3][2] = a[3][0]+b[0][2]
"""
a.shape: (5, 1) b.shape: (4,)
a=
 [[ 0]
 [10]
 [20]
 [30]
 [40]]
b=
 [0 1 2 3]
c.shape: (5, 4) 
c=
 [[ 0  1  2  3]
 [10 11 12 13]
 [20 21 22 23]
 [30 31 32 33]
 [40 41 42 43]]





'\nc=a+b\n1、满足上面广播规则第1条,将b数组转为二维数组(1,4) 1行4列的\n2、满足广播规则第2条,输入数组:a是5行1列;b是1行4列  结果输出:为5行4列\n'

(1)、微实践–绘制二元函数曲面
image-20220315173914643
补充知识:np.ogrid() 函数生成符合广播机制的数组

import numpy as np

x,y = np.ogrid[0:3:4j,0:4:5j]
print("x=\n",x)
print("y=\n",y)
print("x.shape=",x.shape) # x是4行1列的数组
print("y.shape=",y.shape) # y是1行5列的数组
x=
 [[0.]
 [1.]
 [2.]
 [3.]]
y=
 [[0. 1. 2. 3. 4.]]
x.shape= (4, 1)
y.shape= (1, 5)

ogrid()是一个特殊函数,是通过切片的下标来生成数组(用于广播运算的数组),注意:O:3:4j 类似于np.linsapce(0,3,4)生成0~3的长度为4的数组,而4j中j是语法格式。eg:x,y = np.ogrid[0:3:4j,0:4:5j] 生成x是4行1列(4,1),y是1行5列的数组(1,5)

案例一:将x=[-2,+2],y=[-2,+2]的函数值矩阵绘制为平面图

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm

y,x = np.ogrid[-2:2:200j,-2:2:200j]  #  y 形状(200,1)  x形状(1,200)
z = x*np.exp(-x**2-y**2)

extend1 = [np.min(x),np.max(x),np.min(y),np.max(y)] #x和y的界线

plt.imshow(z,cmap=cm.gray,extent=extend1)  # 将z作为图像显示。cmap是指定颜色映射对象,该颜色映射对象负责把z中的元素值转换为像素点的颜色
plt.colorbar() # 通过颜色条来对应z中值与颜色的关系
plt.show()


在这里插入图片描述

案例二:将x=[-2,+2],y=[-2,+2]的函数值矩阵绘制为3d图

import numpy as np
import mpl_toolkits.mplot3d
from matplotlib import pyplot as plt
from matplotlib import cm

x,y = np.mgrid[-2:2:20j,-2:2:20j]  #mgrid和ogrid是相似的,只是mgrid将形状扩充成为矩阵(20,1)->(20,20)
z = x*np.exp(-x**2--y**2)

fig = plt.figure(figsize=(8,6))
ax = fig.gca(projection='3d')  
ax.plot_surface(x,y,z,cmap=cm.ocean) # ax是子图,由于ax.plot_surface()要求是x,y,z三个数组形状相同
plt.show()


在这里插入图片描述

八、函数库

1、随机数

from numpy import random as nr

r1 = nr.rand(3,3)  # 生成0~1的随机数,3,3表示3行3列
r2 = nr.randn(3,3) # 标准正态分布的随机数 ,3行3列
r3 = nr.randint(0,10,(3,3)) # 生成3行3列,0~9(不包含10)的随机整数

print(r1)
print(r2)
print(r3)
[[0.42866666 0.01237853 0.84190471]
 [0.78209189 0.69903899 0.30133983]
 [0.69286253 0.0074816  0.43684253]]
[[-0.37057477 -0.29598364 -0.32416453]
 [-1.14480703  0.19834707  0.3658034 ]
 [-0.63920883 -0.15876545  0.93713387]]
[[5 8 1]
 [4 0 8]
 [4 6 5]]
[0 0]

其他随机数表

  • normal() 正态分布随机数
  • poisson() 泊松分布随机数
  • shuffle() 随机打乱顺序
    - seed() 设置随机数种子
  • uniform() 均匀分布随机数
    - permulation() 随机排列
  • choice() 随机抽取样本

python或者numpy中随机数,都是伪随机数,即随机数是以种子为基础迭代计算。从相同的随机数出发可以获取相同的随机数序列。

微实践——人群身高的正态分布
from numpy import random as nr
import numpy as np
from matplotlib import pyplot as plt

heights = nr.normal(170,30,(10000,)).astype(int)  #生成标准值为170,方差为30,10000个样本的随机数组

stats = np.zeros((10000,))  # 生成一个 10000的一维数组
print(stats.shape,stats.ndim)
for i in range(10000):
    stats[heights[i]]+=1  # stats以身高为下标,统计heights中有多少人,将人数赋值个对应下标的元素,即人数就是stats的元素值
plt.plot(stats[:300])  
plt.show()
[199 131 190 188 133 185 192 175 223 155]
(10000,) 1

在这里插入图片描述

2、和、均值与方差

import numpy as np
from numpy import random as nr

nr.seed(2022) # 设置随机种子,可以使多次运行的结果相同
a = nr.randint(0,10,size=(3,5))
print("a=\n",a)
print("np.sum(a)=",np.sum(a)) # 是数组中的全部元素进行统计
print("np.sum(a,axis=1)=",np.sum(a,axis=1))  # 相同行进行统计
print("np.sum(a,axis=0)=",np.sum(a,axis=0)) # 相同列进行统计
a=
 [[0 1 1 0 7]
 [8 2 8 0 5]
 [9 1 3 8 0]]
np.sum(a)= 53
np.sum(a,axis=1)= [ 9 23 21]
np.sum(a,axis=0)= [17  4 12  8 12]

平均函数 mean()加权平均函数average()

import numpy.random as nr
import numpy as np

nr.seed(2022) #相同的随机种子,后面的随机序列的数组相同
a = nr.randint(0,10,(3,5))
print("a=\n",a)
print("np.mean(a)=",np.mean(a))
print("np.mean(a,axis=1)=",np.mean(a,axis=1))  # 相同的行算平均数
a=
 [[0 1 1 0 7]
 [8 2 8 0 5]
 [9 1 3 8 0]]
np.mean(a)= 3.533333333333333
np.mean(a,axis=1)= [1.8 4.6 4.2]
# 加权平均数
import numpy as np

score = np.array([66,77,88])
weights = np.array([0.3,0.5,0.2]) 
print("np.average(score,weights=weights)=",np.average(score,weights=weights)) # weight 是权数 
np.average(score,weights=weights)= 75.9

补充知识:

  • sum() 求和
  • average() 求加权平均数
  • var() 求方差
  • mean() 求平均数
  • std() 求标准差
  • product() 连乘积

3、比较与排序

比较函数与排序函数

  • max/min() 最大值、最小值
  • minimum、maximum() 二元取最小值、最大值
  • argmin、argmax() 最小值、最大值的下标
  • ptp() 最大值-最小值的结果
  • sort() 排序
  • argsort() 排序后的下标
  • lexsort() 多列排序
  • partition() 快速计算前k项
  • argpartition() 快速计算前k项的下标
  • percentile() 百分数
  • median() 中位数
  • searchsorted() 折半查找
# sort的案例

import numpy as np
from numpy import random as nr

nr.seed(2022) # 设置相同的随机数种子
a = nr.randint(0,10,size=(3,5))
print("a=\n",a)
print("np.sort(a)=\n",np.sort(a))  # sort 进行排序,axis默认是-1,一般是最大轴 eg:二维数 中轴1是最大的
print("np.sort(a,axis=None)=\n",np.sort(a,axis=None))  # 如果axis为None会先将数组转为一维数组,在进行排序
print("np.sort(a,axis=1)=\n",np.sort(a,axis=1))  # axis =1 是按照行进行排序,如果是axis=0是按照列进行排序
print("np.argsort(a,axis=1)=\n",np.argsort(a,axis=1)) # argsort 是获取按行进行排序后数据的下标
a=
 [[0 1 1 0 7]
 [8 2 8 0 5]
 [9 1 3 8 0]]
np.sort(a)=
 [[0 0 1 1 7]
 [0 2 5 8 8]
 [0 1 3 8 9]]
np.sort(a,axis=None)=
 [0 0 0 0 1 1 1 2 3 5 7 8 8 8 9]
np.sort(a,axis=1)=
 [[0 0 1 1 7]
 [0 2 5 8 8]
 [0 1 3 8 9]]
np.argsort(a,axis=1)=
 [[0 3 1 2 4]
 [3 1 4 0 2]
 [4 1 2 3 0]]
# maximum、minimum
import numpy as np
a = np.array([2,4,6,8])
b = np.array([1,3,5,7])

print("np.maximum(a,b)=",np.maximum(a,b))  # 比较a、b对应下标的元素的大小,大的则保存新的数组中
print("a[None,:]=",a[None,:])  #  a.reshape(1,-1)  生成1行4列的数组
print("b[:,None]=\n",b[:,None])  # b.reshape(-1,1)  生成5行1列的数组

print("np.maximum(a[None,:],b[:,None])=\n",np.maximum(a[None,:],b[:,None]))
np.maximum(a,b)= [2 4 6 8]
a[None,:]= [[2 4 6 8]]
b[:,None]=
 [[1]
 [3]
 [5]
 [7]]
np.maximum(a[None,:],b[:,None])=
 [[2 4 6 8]
 [3 4 6 8]
 [5 5 6 8]
 [7 7 7 8]]

np.maximum(a[None,:],b[:,None])
需要将a和b广播机制成为4行4列的元素,下面分别是a和b广播机制后的

  • a 广播机制后的数组

    • [[2 4 6 8]
    • [2 4 6 8]
    • [2 4 6 8]
    • [2 4 6 8]]
  • b广播机制

    • [[1 1 1 1]
    • [3 3 3 3]
    • [5 5 5 5]
    • [7 7 7 7]]
# searchsorted()折半查找法,确定插入位置
import numpy as np
a = np.array([0,2,4,9,10]) # 有序数组
b = np.array([0,1,2,2,4,4,5,8])
print(np.searchsorted(a,b))  #  searchsorted会将b在a中进查找 eg: b[6] 属于的a[2]~~[3]之间所有返回下标3。  b[7] 在a[2]~~~[3]之间,下标为3
[0 1 1 1 2 2 3 3]

4、乘积

补充知识:

  • dot() 矩阵乘积 (行*列)
  • inner() 内积
  • outter() 外积
  • tensordot() 张量乘积
import numpy as np
from numpy import random as nr

nr.seed(2022) 
a = nr.randint(0,5,(2,3))  # 2行3列
b = nr.randint(0,5,(3,2))  # 3行2列
print("a=\n",a)
print("b=\n",b)
c = np.dot(a,b)  # a*b  (2,3)*(3,2) 构成了(2,2)
print("c=\n",c)
d = np.dot(b,a) # b*a (3,2)*(2,3) 构成了(3,3)
print(d)
a=
 [[4 0 1]
 [1 0 0]]
b=
 [[2 0]
 [0 1]
 [1 3]]
c=
 [[9 3]
 [2 0]]
[[8 0 2]
 [1 0 0]
 [7 0 1]]

5、数组的连接

  • (1)concatenate 默认参数axis=0代表是竖直连接,axis=1代表是横向连接
  • (2)hstack 横向连接
  • (3)vstack 竖向连接

分割:

  • (1)、split 默认参数axis=0是竖直方向,按行进行分割
  • (2)、hsplit 是水平分割,按列进行分割
  • (3)、vsplit 是竖直分割,按行进行分割
import numpy as np
arr = np.arange(0,12).reshape(3,4)  # 3行 4列
arr1 = np.arange(2,14).reshape(3,4)
print(np.concatenate((arr,arr1),axis=1))  # 行不变,列增加
print(np.concatenate((arr,arr1)))  # 列不变,行增加

print(np.hstack((arr1,arr))) # 行不变,列增加
print(np.vstack((arr1,arr))) # 列不变,行增加

[[ 0  1  2  3  2  3  4  5]
 [ 4  5  6  7  6  7  8  9]
 [ 8  9 10 11 10 11 12 13]]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 2  3  4  5]
 [ 6  7  8  9]
 [10 11 12 13]]
[[ 2  3  4  5  0  1  2  3]
 [ 6  7  8  9  4  5  6  7]
 [10 11 12 13  8  9 10 11]]
[[ 2  3  4  5]
 [ 6  7  8  9]
 [10 11 12 13]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

(6)、tolist 将数组转换为列表

import numpy as np
arr = np.arange(12).reshape(3,4)
print(arr.tolist(),type(arr.tolist()))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]] <class 'list'>

九、创建矩阵和计算

(一)、创建矩阵 :mat()、matrix()、bmat()函数

  • 1、使用字符串来创建矩阵(MATLAB 风格的)
    • 以空格进行分割列,以分号进行分割
    • eg: numpy.mat(“1 2 3;4 5 6;7 8 9”)
  • 2、使用嵌套序列创建矩阵
    • eg: numpy.mat([[1,2,3,],[4,5,6]])
  • 3、使用数组创建矩阵
    • eg:numpy.mat(np.arange(12).reshape(3,4))
  • 4、使用matrix()创建矩阵
  • 5、bmat() 将小矩阵拼接成大矩阵
import numpy as np
# 使用字符串来创建矩阵
str = '1 2 3;4 5 6;7 8 9'
a = np.mat(str)
a[1,1] = 1
print("查看修改后的a和str\n",a,"\n",str)  #  a矩阵发生了变化,但是str没有发生变化

# 使用嵌套序列创建矩阵
a1 = np.mat([[2,4,6,8],[1.0,3,5,7.0]])
print("嵌套序列创建矩阵:\n",a1)

# 使用数组创建矩阵
arr = np.arange(9).reshape(3,3)
a2 = np.mat(arr)
print("数组创建矩阵:\n",a2)


查看修改后的a和str
 [[1 2 3]
 [4 1 6]
 [7 8 9]] 
 1 2 3;4 5 6;7 8 9
嵌套序列创建矩阵:
 [[2. 4. 6. 8.]
 [1. 3. 5. 7.]]
数组创建矩阵:
 [[0 1 2]
 [3 4 5]
 [6 7 8]]

十、文件读写操作

(一)、读写文本文件

  • loadtxt() 进行读操作
  • savetxt()进行写操作
1、将一维和二维数组写入txt或者csv文件中

格式:numpy.savetxt(fname,array,fmt=“%.18e”,delimiter=None,newline=‘\n’,header=‘’,footer=‘’,comments=‘#’,encoding=None)

  • fname:文件名,可以为.gz和.bz2
  • array: 存入文件的数组
  • fmt:写入文件的格式
  • delimiter:分隔符,默认是空格
  • newline:换行符
  • header:在文件开头写入的字符串
  • footer:在文件末尾写入的字符串
  • comments:字符串标记注释符,默认为#
import numpy as np
arr = np.arange(12).reshape(3,4)

# fmt 默认是%.18(字符串),分隔符是空格
np.savetxt("test1.txt",arr)

# 写入文件的为十进制整数
np.savetxt("test2.txt",arr,fmt="%d",delimiter=',')

#加上注释
np.savetxt("test3.txt",arr,fmt="%d",delimiter=',',header="练习在开头插入字符串啦",footer="和开头的字符串一样呀")

# 修改comments注释符
np.savetxt("test4.csv",arr,fmt="%d",delimiter=",",header="注意观察开头的符号是什么,还是不是#开头的啦",)
2、读取Txt文件和CSV文件

使用函数loadtxt(),该函数格式:numpy.loadtxt(fname,dtype=<type “float”>,comments=“#”,delimiter=None,converters=None,skiprows=0,usecols=None,unpack=False,ndmin=0,encoding=“bytes”)

  • fname:文件、字符串或产生器
  • dtype:数据类型
  • delimiter:分割符
  • usecols:选取数据列表
import numpy as np
arr = np.zeros((3,5),dtype=np.int32)
print(arr)
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
import numpy as np
arr = np.arange(16).reshape(4,4)
# print(arr)
# 切片
print(arr[1,:])

#元组来进行切片
print(arr[(1,1,1,1),(0,1,2,3)]) 
# 数据进行切片
print(arr[[1,1,1,1],[0,1,2,3]]) 

print(arr[1:3,1:3]) 

[4 5 6 7]
[4 5 6 7]
[4 5 6 7]
[[ 5  6]
 [ 9 10]]
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.show()

在这里插入图片描述

import matplotlib.pyplot as plt
plt.plot([1,2,3,4],[1,4,9,16],'rv')
plt.axis([0,5,0,18])  # 前面两个是 x轴 起点和终点 ,后面两个是y轴的起点和终点
plt.show()


在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,10,100)
y = np.cos(x)
plt.plot(x,y)
plt.axis([0,10,-1,1])
plt.show()


在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值