首页 > Numpy学习笔记(下篇)

Numpy学习笔记(下篇)

目录

  • Numpy学习笔记(下篇)
    • 一、Numpy数组的合并与分割操作
    • 1、合并操作
      • 2、分割操作
    • 二、Numpy中的矩阵运算
      • 1、Universal Function
      • 2、矩阵运算
      • 3、向量和矩阵运算
    • 三、Numpy中的聚合操作
    • 四、Numpy中的arg运算
      • 1、索引操作
      • 2、排序和索引使用
    • 五、Fancy Indexing
    • 六、Numpy.array的比较
    • 我是尾巴

Numpy学习笔记(下篇)


路漫漫其修远兮,吾将上下而求索!Numpy学习笔记(上篇)

一、Numpy数组的合并与分割操作

​ 在机器学习算法的使用中会经常使用这两种操作。

1、合并操作

import numpy as np
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
z = np.array([666, 666, 666])
  • np.concatenate([,], axis=) 默认axis=0,拼接之后返回的是一个新的数组。不改变原有数组。
np.concatenate([x, y])

运行输出结果:array([1, 2, 3, 3, 2, 1])

np.concatenate([x, y, z])

运行输出结果:array([ 1, 2, 3, 3, 2, 1, 666, 666, 666])

​ 上面是对一维数组的拼接,接下来看看二维的。

A = np.array([[1, 2, 3],[4, 5, 6]])    # A.shape=(2,3),从第一个维度上拼接就是(4,3)
np.concatenate([A, A])

运行输出结果:

array([[1, 2, 3],[4, 5, 6],[1, 2, 3],[4, 5, 6]])
np.concatenate([A, A], axis=1)      # 从第二个维度上拼接就是(2,6)

运行输出结果:

array([[1, 2, 3, 1, 2, 3],[4, 5, 6, 4, 5, 6]])

​ 那么,能不能把A和z拼接到一起呢?显然是不能的,因为z是1维数组,而A是2维数组,运行会报错。z.shape=(3,),此时我们就可以使用reshape操作将其先装换为2维数组,然后再进行拼接。

np.concatenate([A, z.reshape(1, -1)])

运行输出结果:

array([[  1,   2,   3],[  4,   5,   6],[666, 666, 666]])

​ 其实,在numpy中已经封装好了一个函数用来解决不同维度之间的合并问题。

  • np.vstack()
np.vstack([A, z])

运行输出结果:

array([[  1,   2,   3],[  4,   5,   6],[666, 666, 666]])
  • np.hstack()
B = np.full((2, 2), 100)
np.hstack([A, B])
array([[  1,   2,   3, 100, 100],[  4,   5,   6, 100, 100]])

2、分割操作

  • np.split(x, [,], axis=)

    第一个参数是分割对象,第二个参数是分割点,且分割点可以不唯一。axis默认是0

x = np.arange(10)
x

运行输出结果:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.split(x, [3, 7])

运行输出结果:[array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])]

​ 同样的,接下来试一下二维数组。

A = np.arange(16).reshape(4, 4)
A

运行输出结果:

array([[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11],[12, 13, 14, 15]])
np.split(A, [3])

运行输出结果:

[array([[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11]]), array([[12, 13, 14, 15]])]
np.split(A, [3], axis=1)

运行输出结果:

[array([[ 0,  1,  2],[ 4,  5,  6],[ 8,  9, 10],[12, 13, 14]]), array([[ 3],[ 7],[11],[15]])]

​ 其实,在numpy中既然有垂直水平拼接,那就有垂直水平分割。

  • np.vsplit()
np.vsplit(A, [3])

运行输出结果:

[array([[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11]]), array([[12, 13, 14, 15]])]
np.hsplit(A, [3])

运行输出结果:

[array([[ 0,  1,  2],[ 4,  5,  6],[ 8,  9, 10],[12, 13, 14]]), array([[ 3],[ 7],[11],[15]])]

​ 通过以上对比可以发现:其实vsplit就是split的axis=0的时候,而hsplit就是split的axis=1的时候!

​ 那么接下来做一个简答的小练习,现在有下面一组数据,前三列为数据,最后一列为样本标签,此时我们需要将其分割开来,同时把标签(最后一列)转换为向量:

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11],

[12, 13, 14, 15]])

data = np.arange(16).reshape(4, 4)
x, y = np.hsplit(data, [-1])

运行输出结果:

array([[ 0,  1,  2],[ 4,  5,  6],[ 8,  9, 10],[12, 13, 14]])
array([[ 3],[ 7],[11],[15]])

​ 接下来需要把array转换为向量。

y[:, 0]

运行输出结果:array([ 3, 7, 11, 15])

二、Numpy中的矩阵运算

​ 现在有这么一个问题:给定一个向量,让向量中的每一个元素乘以2,a=(0,1,2),a*2=(0,2,4)

L = [i for i in range(10)]
L * 2

运行输出结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

​ 显然这不是我们想要的结果。那么想要实现怎么办呢?

A = []
for i in L:A.append(i * 2)
A

运行输出结果:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

​ 这肯定不是最优的办法,下面就来对比几种实现方式的快慢。

%%time
L = [i for i in range(100000)]
A = []
for i in L:A.append(i * 2)
A

运行输出结果:Wall time: 14.6 ms

%%time
L = [i*2 for i in range(100000)]

运行输出结果:Wall time: 6.83 ms

%%time
import numpy as np
A = np.array(i*2 for i in range(100000000000000))
A
%%time
L = np.arange(10)
L * 2
L

运行输出结果:Wall time: 0 ns

​ 为什么是0呢?其实因为A返回的是一个生成器,无论后面有多大的的数都是一样的。这就是numpy在大数据运算中的优势所在。关于生成器。

import numpy as np
L = np.arange(10)
L * 2

运行输出结果:array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])

1、Universal Function

X = np.arange(1, 16).reshape(3, 5)
X

运行输出结果:

array([[ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10],[11, 12, 13, 14, 15]])
  • 加法
X + 1

运行输出结果:

array([[ 2,  3,  4,  5,  6],[ 7,  8,  9, 10, 11],[12, 13, 14, 15, 16]])
  • 减法
array([[ 0,  1,  2,  3,  4],[ 5,  6,  7,  8,  9],[10, 11, 12, 13, 14]])
  • 乘法
X * 2

运行输出结果:

array([[ 2,  4,  6,  8, 10],[12, 14, 16, 18, 20],[22, 24, 26, 28, 30]])
  • 除法
X / 2

运行输出结果:

array([[0.5, 1. , 1.5, 2. , 2.5],[3. , 3.5, 4. , 4.5, 5. ],[5.5, 6. , 6.5, 7. , 7.5]])
X // 2

运行输出结果:

array([[0, 1, 1, 2, 2],[3, 3, 4, 4, 5],[5, 6, 6, 7, 7]], dtype=int32)
  • 取余
X % 2

运行输出结果:

array([[1, 0, 1, 0, 1],[0, 1, 0, 1, 0],[1, 0, 1, 0, 1]], dtype=int32)
  • 倒数——1/X
  • 绝对值——np.abs()
  • 正弦函数——np.sin()
  • 余弦函数——np.cos()
  • 正切函数——np.tan()
  • 同样还有反正弦、反余弦、反正切等等。
  • 指数函数——np.exp()
  • np.power()
  • np.log()
  • np.log2()
  • np.log10()

2、矩阵运算

A = np.arange(4).reshape(2, 2)
B = np.full((2, 2), 10)
  • A+B

  • A-B

  • A*B

  • A/B

    ​ 以上方法都是对应元素进行相应操作,那么如果需要进行矩阵乘法怎么办?

  • 矩阵乘法——np.dot()

A.dot(B)

运行输出结果:

array([[10, 10],[50, 50]])
  • 矩阵转置
A.T

运行输出结果:

array([[0, 2],[1, 3]])
  • 矩阵的逆——np.linalg.inv()
np.linalg.inv(A)

运行输出结果:

array([[-1.5,  0.5],[ 1. ,  0. ]])
np.linalg.inv(A).dot(A)

运行输出结果:

array([[1., 0.],[0., 1.]])

​ 这也验证了A*A[^-1]=E

  • 矩阵的伪逆——np.linalg.pinv()

    很多情况下,我们的矩阵可能不是一个方阵,那么此时正常情况下我们是无法求得矩阵的逆的。但是可以求得伪逆矩阵。

C = np.arange(0, 16).reshape(2, 8)
C = np.arange(0, 16).reshape(2, 8)

运行输出结果:

array([[-1.35416667e-01,  5.20833333e-02],[-1.01190476e-01,  4.16666667e-02],[-6.69642857e-02,  3.12500000e-02],[-3.27380952e-02,  2.08333333e-02],[ 1.48809524e-03,  1.04166667e-02],[ 3.57142857e-02, -1.04083409e-17],[ 6.99404762e-02, -1.04166667e-02],[ 1.04166667e-01, -2.08333333e-02]])
C.dot(np.linalg.pinv(C))

运行输出结果:

array([[ 1.00000000e+00, -2.49800181e-16],[ 0.00000000e+00,  1.00000000e+00]])

​ 通过上述结果可以发现,近似单位矩阵说明求得是伪逆矩阵,近似得到的。具体伪逆矩阵的详细求解自行百度!

3、向量和矩阵运算

A = np.arange(4).reshape(2, 2)
v = np.array([1, 2])
  • v+A
v + A

运行输出结果:

array([[1, 3],[3, 5]])
np.vstack([v] * A.shape[0])

运行输出结果:

array([[1, 2],[1, 2]])
np.vstack([v] * A.shape[0]) + A

运行输出结果:

array([[1, 3],[3, 5]])

​ 此时,可以发现两者得到的结果是相同的。其实在pyhon中已经封装了堆叠的函数

  • np.tile()
np.tile(v, (2, 1))

运行输出结果:

array([[1, 2],[1, 2]])
np.tile(v, (2, 1)) + A

运行输出结果:

array([[1, 3],[3, 5]])
  • v *A
v * A

运行输出结果:

array([[0, 2],[2, 6]])
  • A.dot(v)
A.dot(v)

运行输出结果:array([2, 8])

  • v.dot(A)
v.dot(A)

运行输出结果:array([4, 7])

三、Numpy中的聚合操作

import numpy as np
L = np.random.random(100)

运行输出结果:

array([0.21395159, 0.90268106, 0.88705369, 0.11517909, 0.62676208,0.56121013, 0.62103571, 0.2418181 , 0.13781453, 0.66670862,0.51939238, 0.99679432, 0.06384017, 0.5974129 , 0.22196488,0.93826983, 0.83706847, 0.63491905, 0.48828241, 0.85424059,0.86514318, 0.47937265, 0.34254143, 0.89577197, 0.14823176,0.94488872, 0.57030248, 0.57643624, 0.08268558, 0.8237711 ,0.21887705, 0.46440547, 0.9338367 , 0.132422  , 0.4867988 ,0.6545799 , 0.36226663, 0.01641314, 0.67876507, 0.35811434,0.36533195, 0.12174504, 0.37477359, 0.98791281, 0.20553232,0.65235494, 0.13567244, 0.92317556, 0.82237976, 0.62747037,0.41160535, 0.46839494, 0.06753446, 0.22386476, 0.20821765,0.11778734, 0.8643039 , 0.77497708, 0.9884161 , 0.65142779,0.2374325 , 0.32467954, 0.81959546, 0.9863651 , 0.54072234,0.21293241, 0.92733881, 0.98738362, 0.90565471, 0.23441948,0.05477787, 0.69157053, 0.49194796, 0.12415383, 0.55427813,0.29040539, 0.20166942, 0.30054924, 0.30772375, 0.90932004,0.84668024, 0.51970052, 0.67773186, 0.37401172, 0.43911304,0.98495573, 0.42493635, 0.83658015, 0.35920119, 0.91977698,0.95094167, 0.03354397, 0.92045222, 0.80083071, 0.03480189,0.22378161, 0.21437509, 0.33268728, 0.51601075, 0.61235958])
  • 求和——np.sum()
sum(L)

运行输出结果:52.28029464862967

np.sum(L)

运行输出结果:52.28029464862967

​ 那么这两者有什么不一样呢?其实就是单纯的效率上不一样。

  • 最小值——np.min()
np.min(L)

运行输出结果:0.016413139615859218

  • 最大值——np.max()
np.max(L)

运行输出结果:0.9967943174823842

​ 接下来,试一下二维数组。

X = np.arange(16).reshape(4, -1)
X

运行输出结果:

array([[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11],[12, 13, 14, 15]])
np.sum(X)

运行输出结果:120

​ 但是,很多时候我们并不是需要将所有的数进行求和,而是只需要求每一行或者每一列的和。

np.sum(X, axis=0)

运行输出结果:array([24, 28, 32, 36])

np.sum(X, axis=1)

运行输出结果:array([ 6, 22, 38, 54])

​ 在这里,放一个小技巧,axis=0其实就是要把行压缩掉,那就是说不管有多少行直接压缩为一行,那也就是将每一行放在一起求和,axis=1其实就是把列压缩掉,最终的结果就是每一行出一个数。因为按行求和和按列求和记起来其实并不是那么方便。

  • 累乘——np.prod()
np.prod(X)

运行输出结果:0

np.prod(X + 1)

运行输出结果:2004189184

  • 均值——np.mean()
np.mean(X)

运行输出结果:7.5

  • 中位数——np.median()
np.median(X)

运行输出结果:7.5

  • 百分位——np.precentile()
X = np.arange(16).reshape(4, -1)
for percent in [0, 25, 50, 75, 100]:print(np.percentile(X, q=percent))

运行输出结果:

0.0
3.75
7.5
11.25
15.0
  • 方差——np.var()
np.var(X)

运行输出结果:21.25

  • 标准差——np.std()
np.std(X)

运行输出结果:4.6097722286464435

四、Numpy中的arg运算

1、索引操作

  • np.argmin() # 最小值所在位置的索引
  • np.argmax() # 最大值所在位置的索引

2、排序和索引使用

# 首先生成一个乱序数组
import numpy as np
x = np.arange(16)
np.random.shuffle(x)
x

运行输出结果:array([ 4, 2, 8, 14, 0, 15, 6, 3, 11, 7, 13, 1, 12, 10, 9, 5])

  • np.sort(x, axis=) 默认axis=1
np.sort(x)

运行输出结果:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])

​ 此时,并没有改变x,x仍是一个乱序的状态,如果想要直接在x上进行排序:

x.sort()
x

运行输出结果:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])

​ 那么对于二维矩阵呢?

X = np.random.randint(10, size=(4, 4))
X

运行输出结果:

array([[5, 3, 9, 2],[3, 7, 5, 7],[0, 6, 2, 0],[8, 7, 4, 8]])
np.sort(X, axis=0)

运行输出结果:

array([[0, 3, 2, 0],[3, 6, 4, 2],[5, 7, 5, 7],[8, 7, 9, 8]])
  • np.argsort() 按照索引位置排序
import numpy as np
x = np.arange(16)
np.random.shuffle(x)
np.argsort(x)

运行输出结果:

array([ 1, 15,  9,  0, 10,  8, 12, 13,  5,  4,  6,  2,  3, 14, 11,  7],dtype=int64)
  • np.partition()

    其实,在很多情况下,我们并不需要将所有数进行从大到小排序,而是寻找一个中间值,小于中间值的在左边,大于中间值的在右边。

np.partition(x, 3)

运行输出结果: array([ 0, 1, 2, 3, 9, 8, 10, 12, 5, 11, 4, 14, 6, 7, 13, 15])

  • np.argpartition()
np.argpartition(x, 3)

运行输出结果:

array([ 1, 15,  9,  0,  4,  5,  6,  3,  8,  2, 10, 11, 12, 13, 14,  7],dtype=int64)

五、Fancy Indexing

import numpy as np
x = np.arange(16)

​ 如果我们需要从3-9每间隔2个取一个数?

x[3:9:2]

运行输出结果: array([3, 5, 7])

​ 如果我们需要去取得数据不是等间距的呢?

idx = [3, 5, 8]
x[idx]

运行输出结果:array([3, 5, 8])

ind = np.array([[2, 3],[4, 5]])
x[ind]

运行输出结果:

array([[2, 3],[4, 5]])
X = x.reshape(4, -1)
row = np.array([0, 1, 2])
col = np.array([1, 2, 3])
X[row, col]

运行输出结果:array([ 1, 6, 11])

col = [True, False, True, True]
X[1:3, col]

运行输出结果:

array([[ 4,  6,  7],[ 8, 10, 11]])

六、Numpy.array的比较

import numpy as np
x = np.arange(16)
x > 3

运行输出结果:

array([False, False, False, False,  True,  True,  True,  True,  True,True,  True,  True,  True,  True,  True,  True])
  • '>'

  • '<'

  • '>='

  • '<='

  • '=='

  • '!='

    ​ 结合刚刚学过的聚合操作,进行一些练习。

np.sum(x <= 3)

运行输出结果:4

np.sum((x >= 3) & (x <= 10))

运行输出结果:8

np.count_nonzero(x <= 3)        # True为1,False为0

运行输出结果:4

  • np.any()
  • np.all()
  • 与——&
  • 或——|
  • 非——~

我是尾巴

​ 每篇一句毒鸡汤:千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。

我干了,你随意!

本次推荐:一款图片阅读器,预览更轻松

honeyview

坚持!

转载于:https://www.cnblogs.com/zhangkanghui/p/11280845.html

更多相关:

  • SearchRequestBuilder常用方法说明 (1) setIndices(String... indices):上文中描述过,参数可为一个或多个字符串,表示要进行检索的index;(2) setTypes(String... types):参数可为一个或多个字符串,表示要进行检索的type,当参数为0个或者不调用此方法时,...

  • 继续: 经过上文的分析,似乎可以得到类似这样的想法:   由此 分为左右两侧进行区分绘制,应该就可以获得想要的结果了~   转载于:https://www.cnblogs.com/loveclumsybaby/p/3440314.html...

  • 首次运行Alt+R    然后继续Enter直到运行npm start为止...

  • 运行命令control打开控制面板 运行telnet命令就可以了...

  •     cnpm install -g create-react-app 找一个创建项目的目录,用cmd打开资源管理器对应目录运行 create-react-app demo 注意:安装过程中最好焦点不要移出cmd窗口,有时候会莫名其妙的中断安装 最后运行即可 cd democnpm start 运行成功后...

  •   win+R 运行sysdm.cpl 运行cmd mvn -v 如果不是这样就运行path 看下安装路径是否正确重新配置sysdm.cpl...

  • canrun 测试运行HTML 测试博客园HTML源码运行程序

  • 全卷积网络(FCN) 1.全卷积神经网络介绍 FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全联接层+softmax输出)不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的fea...

  • printf()函数优点在于可以格式化输出 格式:   %['padding_character][-][width][.precision]type   所有的转换说明都是以%开始,如果想打印一个%符号,必须用%% ;   参数“'padding_character”是可选,它将被用来填充变量直至所指定的宽度,该参...

  • 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。 输入格式: 输入在一行中给出一个长度不超过10000的、仅...

  • 给定两个整数A和B,输出从A到B的所有整数以及这些数的和。 输入格式: 输入在一行中给出2个整数A和B,其中−100≤A≤B≤100,其间以空格分隔。 输出格式: 首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X。 输入样例:...

  • python面试题目 原文地址:https://www.usblog.cc/blog/post/justzhl/b5cc9a05c7d2 问题一:以下的代码的输出将是什么? 说出你的答案并解释。 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Parent(object):     x...