# https://numpy.org/devdocs/user/quickstart.html
#推荐 https://www.yiibai.com/numpy/
#https://www.jianshu.com/p/83c8ef18a1e8
# NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用。
#NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,
#此外也针对数组运算提供大量的数学函数库。Numpy内部解除了Python的PIL(全局解释器锁),
#运算效率极好,是大量机器学习框架的基础库!
# pip install numpy
import numpy as np
a=[1,2,3,4]
b=np.array(a)
print(a)
print(b)
print("1>",b.size) #数组元素个数
print("2>",b.shape) #数组形状
print("3>",b.ndim) #数组维度
print("4>",b.dtype) #数组元素类型
print("5>",b.itemsize) #对象中每个元素的大小,以字节为单位
# 一维数组
a=np.array([1,23,4])
b=np.array((1,23,4))
print('a=',a, '; b=',b)
## 指定数据类型
a=np.array([1,23,4],dtype=np.int)
print(a.dtype, a) #np.array([1,23,4])
a=np.array([1,23,4],dtype=np.float)
print(a.dtype, b) #float64
# 二维数组
array=np.array([
[1,2,3],
[4,5,6]
])
array
# 获取元素(从0开始计数)
print(len(array), array[0]) #2个元素(每个元素也是数组),第0个元素是数组[1 2 3]
print(len(array[0]), array[0][1], array[0,1]) #第0个元素长度是3,里面的第一个元素是2;
# 二维数组的元素,可以[i][j]获取,也可以[i,j]获取
# 获取数组的元素总数,形状,维度个数
print(array.size)
print(array.shape)
print(array.ndim)
print(array.dtype)
print(array.dtype.name)
print(array.itemsize)
type(array)
# 行列转置
array.T
reshape()能把arange()产生的数据序列再排序,按照第一维从左到右,其余从上到下;
#一维数组
a=np.arange(12)
print("a=",a)
#变成4行3列
a2=a.reshape(4,3)
print('a2=',a2)
#变成竖排的4行3列,思路:先变成3行4列,再行列转置
a3=a.reshape(3,4).T
print('a3=',a3)
# 更高维度的数组
a=np.arange(24).reshape(2,3,4) #2个,每个3行4列。C语言风格的下标,越往后的维度,下标变动越快。
a
print(a[0], "\n") #最外围的维度,包含元素越多。
print(a[0][0], a[0][0][1], "\n") #最外围的第一个维度中,下一维度是行,最后是列(一个数字)
print(a[1])
a=np.zeros((3,4));
print(a) #3行4列的0矩阵。
np.ones((2,4)) #2行4列的1矩阵
np.identity(4) #单位矩阵
np.empty( (6, 6) ) # uninitialized #空矩阵,受到上一个初始化矩阵的影响
有2种实现:
# arange区间是[左闭,右开)的,参数顺序 start, end, space
a1=np.arange(10,20) #array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
a2=np.arange(10,20,2) #等差是2 array([10, 12, 14, 16, 18])
print(a1)
print(a2)
#在-5,5之间,每隔0.5产生一个数
np.arange(-5,5,0.5)
#太多则显示时会跳过
print(np.arange(10000))
#更严谨的,对小数位数控制更精确的是np.linspace()
#在-5,5之间,相同间隔,产生n=10个数字
np.linspace(-5,5,10)
# 常用于画图时的坐标
x = np.linspace( 0, 2*np.pi, 50 ) # useful to evaluate function at lots of points
f = np.sin(x)
print(len(f), f[0:10])
import matplotlib.pyplot as plt
plt.scatter(x,f)
plt.show()
# 切片也是[左闭右开)区间
t=np.arange(10)**3
print(t[0]) #取出一位
print(t[0:1]) #数组切片后还是数组
t
t[8:100] #多了也没有,也不报错。只显示能显示的位数
t[2:5] # [左闭右开)
# 第三个参数是间隔
print(t[::2]) # from start to end, every 2 item: 0,2,4, ...
print(t[:6:2]) # [0, 6) 每隔2个取一个
t[::-1] # reversed
for i in t:
print(i, "\t", i**(1 / 3))
# np增加一个元素
a1=np.array([1,2,3])
a2=np.append(a1,400)
print(a1,a2) #说明不改变原来的值
# 删除一个元素
a=np.array([1,2,3])
a2=np.delete(a,1,axis=0)
print(a,a2)
# 删除多个元素
a=np.array([1,2,3,4,5,6])
a2=np.delete(a,[2,3,4],axis=0) #删除2,3,4位置的元素: 3,4,5,留下的是1,2,6
print(a,a2)
np.random.random((2,3))
a=np.arange(12).reshape(3,4)
a
a==8
b=np.where(a==8)
print(b)
print(b[0], b[1]) #8在第2行第0列
print(b[0], b[1], '\na[b]=',a[b], '\na[a==8]=',a[a==8])
help(np.where)
# 通过函数赋值,传入参数是下标
def f2(x,y): #传入坐标
return 10*x + y +0.2
b=np.fromfunction(f2, (5,4), dtype=int)
b
for row in b: #按row迭代
print(row)
#按元素迭代 b.flat
for ele in b.flat:
print(ele)
np数据类型,是对每个元素分别运算。
使用numpy,能减少了for循环的使用。
a=np.array([10,20,40,30])
b=np.arange(4)
print(a,b) #[10 20 40 30] [0 1 2 3]
np.add(a, b) #逐位相加
#加减法,就是逐位运算
c=a-b
print(c)
a*b #逐位相乘
b**2 #乘方
10*np.sin(a) #三角函数
X=np.array([1,2,3]) #幂运算
print(np.exp(X))
np.power(2, [0,1,2,3,4,5])
np.sqrt(b) #开方
#逻辑运算
b>2
np.random.randint(low=5, high=30, size=(5, 5))
np.eye(4)
count=np.array([1,2,3])
price=np.array([20,3,5])
count.dot(price.T)
count.T.dot(price)
count.T #一维没有转置的概念?
#二维行向量,A.BT是数,AT.B是矩阵
count=np.array([[1,2,3]])
price=np.array([[20,3,5]])
count.dot(price.T)
count.T.dot(price)
A = np.array( [[1,1,0],
[0,1,2]] )
B = np.array( [[2,0],
[3,4],
[5,6]] )
print(A)
print()
print(B)
print(A@B) #或者
A.dot(B)
import numpy as np
a=np.array([
[1,2,3],
[4,5,6],
[7,8,0]
])
print(a)
## 变为矩阵
matA=np.mat(a)
b=matA.I
print(matA)
b
type(matA)
matA@b #矩阵*其逆矩阵 = 单位矩阵
matA@b-np.eye(3)
# 删除b数组中出现过的元素,就是求差集
a=np.array([1,2,3,400])
b=np.array([2,3,4,500])
c=np.setdiff1d(a,b) #a-b的差集
print(a,b,c)
np.random.seed(1)
a=np.random.random([2,3])
print(a)
print('sum=', a.sum())
print('mean=', a.mean())
print('min=', a.min())
print('max=', a.max())
b=np.arange(12).reshape(4,3)
print(b)
print( b.sum() ) #总和 66
print('axis=0:', b.sum(axis=0) ) #列求和
print('axis=1:', b.sum(axis=1) ) #行求和
b.cumsum(axis=1) #每一行的累加
print(b.sum(axis=0) ) # sum of each column
print(b.sum(axis=1) ) # sum of each row
print( b.min(axis=1) ) # min of each row
#
b.cumsum(axis=1) # cumulative sum along each row
print(b)
print(b.ndim) #2 维度
print(b.shape) #(4,3) 4行3列
print(b.size) #12
print(b.dtype) #int64
print('='*10)
print(b.itemsize) #8 等价于下句
print(b.dtype.itemsize) #8
print(b.data) #<memory at 0x0000025D17EDB708> 不常用
print( id(b) )
print(type(b)) #<class 'numpy.ndarray'>
有 reshape, resize, ravel 等几个函数。
a=np.arange(12).reshape((3,4))
print(a.shape)
a
#返回摊平的数组,但是不改变原始数组
#展开的时候,是C语言风格,就是最右侧的下标变动最快
a.ravel()
a.reshape([6,2])
a.reshape(6,2) #参数中加不加[]都一样
print(a.T) # returns the array, transposed 转置
print("转置前", a.shape)
print("转置后", a.T.shape)
# reshape 的一个参数如果是-1,则会根据另一个参数会自动计算
a.reshape(6, -1)
# reshape 不改变原始矩阵,会返回一个新矩阵的 view。
# 但是 resize 则直接改变原始矩阵
a.resize(2,6)
a
a=np.arange(4).reshape(2,2)
b=np.arange(10,14).reshape(2,-1)
print(a,"\n\n", b)
np.vstack( (a,b) ) #垂直合并
np.hstack( (a,b) ) #水平合并
# column_stack 能把1d 数组 当做列 合并为2d数组。对于2d数组,它和hstack输出是一样的。
np.column_stack( (a,b) ) # with 2D arrays, 就是 hstack
np.row_stack( (a,b) ) #对于任意输入,都和vstack一样
# 对于输入1d数组, column_stack 和 hstack 结果不一样。
a1=np.array([1,2,3])
a2=np.array([4,5,6])
print(a1, "\n")
print(a2, "\n")
print(np.column_stack((a1, a2))) #把每个1d数组当做一列,输出2d数组
print(np.hstack( (a1, a2) )) #把数组水平拼接起来
print(np.column_stack is np.hstack) #F 对于输入2d数组时,输出没有差异。输入1d数组时,输出不一样。
print(np.row_stack is np.vstack) #T
help(np.concatenate)
a=np.arange(5)
b=np.array([11,22,33])
print(a,b)
print(np.concatenate((a,b) ) )
np.concatenate((a,b),axis=0) #axis沿着x轴(默认)方向合并数组
a1=np.array([[1,2],[3,4]])
a2=np.array([[10,20]])
print('a1=',a1)
print('a2=',a2)
#
np.concatenate( (a1,a2), axis=0) #加到第0维后面
np.concatenate( (a1,a2.T), axis=1) #加到第一维后面
# 对一组多维数据拼接
a1=np.linspace(1,24,24).reshape(2,3,4)
a1
a2=np.linspace(-1,-24,24).reshape(2,3,4)
a2
a3=np.linspace(1,24,24).reshape(2,3,4)
a3
s=list()
s.append(a1)
s.append(a2)
s.append(a3)
print(s)
ei=np.concatenate(s, axis=1)
ei
es=ei.shape
es
output=ei.reshape(es[0]*es[1], -1)
output
output.reshape(es[0], -1)
a=np.arange(24).reshape(2,12)
print(a)
np.hsplit(a, 3) #水平拆分成3个
# Split `a` after the third and the fourth column
np.hsplit(a, (3, 4))
np.vsplit(a, 2) #沿着竖直方向拆分成2个
# 自己指定方向
np.array_split(a, 2, axis=1) #沿着竖直方向,拆分成2个
a=np.array([
[1,2,3],
[4,5,6]
])
b=a
b is a
# 函数传参不复制
def f3(x):
print(id(x))
print(id(a))
f3(a)
c=a.view() #复制一个副本
c is a
c.base is a # c is a view of the data owned by a ## bug 文档是 True
print(a)
c
print(c.flags)
a.flags
print(c.flags.owndata)
print(a.flags.owndata)
c=c.reshape((3,2)) # a's shape doesn't change
print(c.shape)
a.shape
a[1,:]=1234
c #也随着a而改变
a=a.reshape(2,3)
print(a)
c
# reshape 返回的是一个view
a0=np.arange(12)
a1=a0.reshape(2,6)
print(a1)
print(a1.base is a0)
a1.base
# 切片返回的也是一个view
s=a[:, 1:2]
s[:]=10 #对s的修改,能影响到a
print(s)
a
# 对a的修改也能影响到切片 s
a[0,1]=1000
print(a)
s
a=np.array([
[1,2],
[3,4]
])
a
d = a.copy() # a new array object with new data is created
d is a
d.base is a
d[0,0]=1000 #对d的修改不影响a
print(d)
a
#如果只想保留切片,删除原始数据,则删除前需要 copy 一下。否则被引用着就一直删不掉
a=np.arange(int(1e5))
b=a[:10].copy
del a
b