学习过程中遇到np.mgrid函数,感觉很难理解
其实把输出换成相应的点在坐标系中画出来就很好理解了.
比如说
np.mgrid[0:5, 0:3]
其实是画一个网格一样的点,横坐标从0开始画5个长度,纵坐标从0开始画3个
nodes = np.mgrid[0:5, 0:3]
plt.scatter(nodes[0],nodes[1])
plt.xticks([n for n in range(6)])
plt.yticks([n for n in range(6)])
plt.show()
输出的shape为(2,5,3),是把横坐标保存到第一个数组中,纵坐标保存到第二个数组中
nodes[0]是所有点的横坐标,nodes[1]是所有点的纵坐标
nodes[0][2]是所有横坐标为2的点的横坐标,nodes[1][2]是所有纵坐标为2的点的纵坐标
如果我们要取(2,2)可以这样取(nodes[0][2][2],nodes[1][2][2])
如果这个矩阵被转置了,代表什么?
np.mgrid[0:5, 0:3].T
polyfit函数可以使用最小二乘法将一些点拟合成一条曲线.
numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
x:要拟合点的横坐标
y:要拟合点的纵坐标
deg:自由度.例如:自由度为2,那么拟合出来的曲线就是二次函数,自由度是3,拟合出来的曲线就是3次函数
首先我们先来构造一下需要被拟合的散点
x = np.arange(-1, 1, 0.02)
y = 2 * np.sin(x * 2.3) + np.random.rand(len(x))
然后打印一下看看
plt.scatter(x, y)
plt.show()
然后用polyfit函数来把这些点拟合成一条3次曲线
parameter = np.polyfit(x, y, 3)
输出的结果为3次方程的参数,我们可以像下面这样把方程拼接出来
y2 = parameter[0] * x ** 3 + parameter[1] * x ** 2 + parameter[2] * x + parameter[3]
将拟合后的结果打印一下
plt.scatter(x, y)
plt.plot(x, y2, color='g')
plt.show()
还可以使用**poly1d()**函数帮我们拼接方程,结果是一样的
p = np.poly1d(parameter)
plt.scatter(x, y)
plt.plot(x, p(x), color='g')
plt.show()
首先我们构造一下数据,这是一个(2, 3, 4)格式的list
>>> array = [[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]]]
我们把每个数字用一个方块表示,那么这个list就相当于这样的一堆方块.
>>> a = np.stack(array, axis=0)
>>> a.shape
(2, 3, 4)
>>> a
array([[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]],
[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]]])
我们发现,当axis=0的时候,list和生成的矩阵是一样的,相当于将这些方块分成了三组,先在厚度方向分成两组,然后垂直方向分成3组,最后4个块一组
我们再试试axis=1
>>> b = np.stack(array, axis=1)
>>> b.shape
(3, 2, 4)
>>> b
array([[[1, 2, 3, 4],
[1, 2, 3, 4]],
[[1, 2, 3, 4],
[1, 2, 3, 4]],
[[1, 2, 3, 4],
[1, 2, 3, 4]]])
和上一个类似,只不过这次是先在垂直方向分成3组,然后再厚度方向分成两组
再来看看axis=2
>>> c = np.stack(array, axis=2)
>>> c.shape
(3, 4, 2)
>>> c
array([[[1, 1],
[2, 2],
[3, 3],
[4, 4]],
[[1, 1],
[2, 2],
[3, 3],
[4, 4]],
[[1, 1],
[2, 2],
[3, 3],
[4, 4]]])
先在垂直方向分成3组,然后在水平方向分成4组,最后2个为一组
np.concatenate()的功能和hstack() vstack() dstack()的功能非常相似,大家可以互相参考着看.
numpy.concatenate((a1, a2, ...), axis=0, out=None)
(a1, a2, ...):为需要合并的矩阵
>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
[3, 4],
[5, 6]])
>>> a = np.array([[1],[2],[3]])
>>> b = np.array([[2],[3],[4]])
>>> np.concatenate((a,b), axis=1)
array([[1, 2],
[2, 3],
[3, 4]])
>>> a = [[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]]]
>>> b = [[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]]]
>>> np.concatenate((a,b), axis=2)
array([[[1, 2, 3, 4, 1, 2, 3, 4],
[1, 2, 3, 4, 1, 2, 3, 4],
[1, 2, 3, 4, 1, 2, 3, 4]],
[[1, 2, 3, 4, 1, 2, 3, 4],
[1, 2, 3, 4, 1, 2, 3, 4],
[1, 2, 3, 4, 1, 2, 3, 4]]])
np.random.rand()可以返回任意纬度的矩阵,矩阵内的数值为[0,1)的随机数
np.random.rand(d0,d1,…,dn)
d0~dn:为输出矩阵的纬度
例如:
>>> np.random.rand(2,3)
array([[0.48290715, 0.35586919, 0.82244376],
[0.72144442, 0.52671832, 0.25967954]])
>>> np.random.rand(4,3,2)
array([[[0.04365607, 0.09989154],
[0.29794552, 0.40393603],
[0.13601166, 0.52009022]],
[[0.61301835, 0.92477563],
[0.23488518, 0.24992936],
[0.0665239 , 0.42134488]],
[[0.03398788, 0.50690946],
[0.30294694, 0.65442827],
[0.11361693, 0.61128644]],
[[0.67004488, 0.67306076],
[0.19438974, 0.14208858],
[0.93978535, 0.39877183]]])
np.random.randn()和np.random.rand()非常相似,同样可以获得任意纬度的矩阵,只是返回矩阵内的数值为符合均值为0、标准差为1的正态分布.
np.random.randn(d0,d1,…,dn)
d0~dn:为输出矩阵的纬度
>>> np.random.randn(2,3)
array([[-0.13906226, -0.0093422 , -0.16018623],
[-1.61093869, 0.92672041, -1.07908674]])
>>> np.random.randn(4,3,2)
array([[[-0.47225703, -0.51533159],
[ 0.07488023, -0.10368794],
[ 0.8739207 , -0.4209093 ]],
[[ 0.52181307, 0.23516168],
[-0.11051864, -0.30658818],
[ 1.10396061, -0.20688803]],
[[-1.70228738, 0.40502851],
[ 2.34587959, -0.51460201],
[-0.78227885, -0.60468352]],
[[ 1.70129296, 1.37562914],
[ 1.38122835, -0.72530221],
[ 1.57112625, -0.36154434]]])
np.arange()函数的用法与python中的range()函数很类似
numpy.arange([start, ]stop, [step, ]dtype=None)
我们可以只传一个参数n,会从0开始生成0~n连续的数值,例如:
>>> np.arange(3)
array([0, 1, 2])
>>> np.arange(3.0)
array([ 0., 1., 2.])
还可以指定起始值,例如:
>>> np.arange(3,7)
array([3, 4, 5, 6])
还可以指定步长
>>> np.arange(3,7,2)
array([3, 5])
np.transpose()函数和arr.T都可以获得转置矩阵.两者的区别是arr.T只适用于低维矩阵,而np.transpose()适用于任何维度的矩阵变换.
我们来复习一下转置矩阵的定义:将矩阵的行列互换得到的新矩阵称为转置矩阵.
例如:
np.transpose()函数和arr.T同样适用
>>> arr = np.arange(15).reshape((3, 5))
>>> arr
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> arr.T
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
>>> np.transpose(arr)
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
对于高级矩阵的转置需要在np.transpose()传入参数告诉其应该如何变换坐标轴.
我们先创建一个3维矩阵,并打印出来看看是什么样子的
>>> arr = np.arange(16).reshape(2,2,4)
>>> arr
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
使用参数(0,1,2)
进行转置,发现矩阵没有变化,说明矩阵未转置之前的坐标轴排列就是(0,1,2)
>>> arr.transpose((0,1,2))
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
现在将矩阵的0轴和1轴交互,看一下结果
>>> arr.transpose((1,0,2))
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
np.diag()可以提取一个矩阵的对角线数值,或是提供对角线数值让其构建一个矩阵
>>> x = np.arange(9).reshape((3,3))
>>> x
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> np.diag(x)
array([0, 4, 8])
>>> np.diag(array([0, 4, 8]))
array([[0, 0, 0],
[0, 4, 0],
[0, 0, 8]])
np.flipud()函数可以将矩阵里面的值倒序.
注意:只是在第一个维度上进行倒序哦.
例如:
>>> arr = np.arange(6)
>>> arr
array([0, 1, 2, 3, 4, 5])
>>> np.flipud(arr)
array([5, 4, 3, 2, 1, 0])
如果是多维矩阵也只是在第一个维度上进行倒序.
>>> A = np.diag([1.0, 2, 3])
>>> A
array([[ 1., 0., 0.],
[ 0., 2., 0.],
[ 0., 0., 3.]])
>>> np.flipud(A)
array([[ 0., 0., 3.],
[ 0., 2., 0.],
[ 1., 0., 0.]])
numpy.random.normal(loc=0.0, scale=1.0, size=None)
import matplotlib.pyplot as plt
import numpy as np
# 散点图
x = np.random.normal(0, 1, 1024)
y = np.random.normal(0, 1, 1024)
# 随机颜色
T = np.arctan2(x, y)
plt.scatter(x, y, s=75, c=T, alpha=0.5)
# 设置横纵坐标轴展示范围
plt.xlim((-1.5,1.5))
plt.ylim((-1.5,1.5))
# 隐藏横纵坐标轴
plt.xticks(())
plt.yticks(())
plt.show()
np.where()函数可以用来获取符合条件的值的索引.
例如,我们要获取矩阵中大于2的值的索引.
>>> a = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
>>> idx = np.where(a > 2)
>>> idx
(array([2, 5, 8], dtype=int64),)
np.where()还有一种用法,直接来看代码
x = np.array([1, 2, 3, 4, 5])
y = np.array([11, 12, 13, 14, 15])
condition = np.array([True, False, True, True, False])
result = np.where(condition, x, y)
如果condition为True,那么result的值从x中取.
如果condition为False,那么result的值从y中取.
首先关于numpy在所有场合都不建议这样使用
demo = np.array([1, 2, 3])
因为此时demo.shape是只有一个纬度的
(3,)
永远不要使用这种类型,这会使工作中出现各种各样的问题,并且很多操作都难以理解。如果你想使用是一个一维的矩阵应该定义这样的纬度:
(3, 1)
你如果这样做了,那么下面的函数会非常容易理解和记忆,并且在使用的时候不易出问题。
v是vertical,竖直的意思,将多个矩阵从竖直放心上合并。
a = np.array([1, 2, 3]).reshape(-1,1)
b = np.array([4, 5, 6]).reshape(-1,1)
print(a.shape) # (3, 1)
print(b.shape) # (3, 1)
c = np.vstack((a,b))
print(c.shape) # (6, 1)
看,竖直方向上的合并就是将第一个纬度加起来,多么直观。
h是horizontal水平的意思,可以这样记:水的分子式是h2o,所以h代表水平。
a = np.array([1, 2, 3]).reshape(-1,1)
b = np.array([4, 5, 6]).reshape(-1,1)
print(a.shape) # (3, 1)
print(b.shape) # (3, 1)
c = np.hstack((a,b))
print(c.shape) # (3, 2)
看,水平方向上的合并就是将第一个纬度加起来,多么直观。
d代表deep,深度的意思
a = np.array([1, 2, 3]).reshape(-1,1)
b = np.array([4, 5, 6]).reshape(-1,1)
print(a.shape) # (3, 1)
print(b.shape) # (3, 1)
c = np.dstack((a,b))
print(c.shape) # (3, 1, 2)
它会保持合并后矩阵的结构与原先一致,也就是说我们可以用同样的方法取合并后的数据。
print(a[0][0]) # 1
print(b[0][0]) # 4
print(c[0][0]) # [1, 4]
Numpy中的split()等价于vsplit(),可以使用它来分割矩阵
numpy.split(ary, indices_or_sections, axis=0)
ary
:是待分割的矩阵
indices_or_sections
:可以传数值或是数组,传数值的话会将矩阵分割成数值的份数,如果传数组则按照数组中的大小区间分割.
>>> x = np.arange(9.0)
>>> np.split(x, 3)
[array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7., 8.])]
>>> x = np.arange(8.0)
>>> np.split(x, [3, 5, 6, 10])
[array([ 0., 1., 2.]),
array([ 3., 4.]),
array([ 5.]),
array([ 6., 7.]),
array([], dtype=float64)]