numpy函数详解

np.mgrid()

学习过程中遇到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()

image

输出的shape为(2,5,3),是把横坐标保存到第一个数组中,纵坐标保存到第二个数组中

image

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

image

转置后的shape是(3,5,2)的,和未转置之前的(2,5,3)刚好倒过来
相当于横着保存坐标点,第一行是y为0的所有点,第二行为y为1的所有点....

np.polyfit()与np.poly1d()将点拟合成曲线

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()

image

然后用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()

image

还可以使用**poly1d()**函数帮我们拼接方程,结果是一样的

p = np.poly1d(parameter)
plt.scatter(x, y)
plt.plot(x, p(x), color='g')
plt.show()

np.stack()

首先我们构造一下数据,这是一个(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就相当于这样的一堆方块.

image

我们用axis=0看一下shape,默认情况axis就是等于0的

>>> 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个块一组

image

我们再试试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组,然后再厚度方向分成两组

image

再来看看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个为一组

image

np.concatenate()合并矩阵

np.concatenate()的功能和hstack() vstack() dstack()的功能非常相似,大家可以互相参考着看.

numpy.concatenate((a1, a2, ...), axis=0, out=None)

(a1, a2, ...):为需要合并的矩阵

当axis=0时,矩阵将在第一个纬度上进行合并

>>> 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]])

当axis=1时,矩阵将在第二个纬度上进行合并

>>> 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]])

当axis=2时,矩阵将在第三个纬度上进行合并

>>> 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()与np.random.randn()

np.random.rand()

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.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()

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()转置矩阵

np.transpose()函数和arr.T都可以获得转置矩阵.两者的区别是arr.T只适用于低维矩阵,而np.transpose()适用于任何维度的矩阵变换.

我们来复习一下转置矩阵的定义:将矩阵的行列互换得到的新矩阵称为转置矩阵.
例如:

image

对于低维矩阵(1~2维)

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]]])

image

现在将矩阵的0轴和1轴交互,看一下结果

>>> arr.transpose((1,0,2))
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

image

np.diag()对角线矩阵

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()将矩阵倒序

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.]])

np.random.normal()生成正态分布随机点

image

我们可以用np.random.normal()函数生成正态分布随机点

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()

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中取.

hstack() vstack() dstack()

首先关于numpy在所有场合都不建议这样使用

demo = np.array([1, 2, 3])

因为此时demo.shape是只有一个纬度的

(3,)

永远不要使用这种类型,这会使工作中出现各种各样的问题,并且很多操作都难以理解。如果你想使用是一个一维的矩阵应该定义这样的纬度:

(3, 1)

你如果这样做了,那么下面的函数会非常容易理解和记忆,并且在使用的时候不易出问题。

np.vstack()

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)

看,竖直方向上的合并就是将第一个纬度加起来,多么直观。

np.hstack()

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)

看,水平方向上的合并就是将第一个纬度加起来,多么直观。

np.dstack()

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]

split() vsplit()分割矩阵

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)]
posted @ 2018-03-16 19:13:36
评论加载中...
发表评论