暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Numpy超详细使用

谭西路 2022-05-18
427

1. 初识Numpy


Numpy(Numerical Python的简称)是Python数值计算最重要的基础包,大多数提供科学计算的包都是用Numpy的数组作为构建基础。


Numpy的部分功能如下:


  • ndarry,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。

  • 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。

  • 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。

  • 线性代数、随机数生成以及傅里叶变换功能

  • 用于集成C/C++/Fortran等语言编写的代码的API。


Numpy用于数值计算特别重要的原因之一,是因为它可以高效处理大数组的数据。这是因为:


  • Numpy是一个连续的内存块中存储数据,比起Python的内置序列,Numpy数组使用的内存更少。

  • Numpy可以在整个数组中执行复杂的计算,而不需要Python的for循环。


注:矢量化运算:不需要编写for循环的情况下进行批量运算


本篇文章将具体学习Numpy的知识点如下:


  • 如何创建Numpy的ndarray数组对象

  • 数组的索引和切片功能

  • 数组的运算和常用函数

  • 数组的统计方法

  • 数组的排序和集合逻辑

  • 数组的文件输入和输出

  • 随机数生成

  • 线性代数

  • 高级应用


1. 创建Numpy的ndarray数组对象


创建数组最简单的方法是使用array函数,它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组。


import numpy as np
# 1. 列表创建数组
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)

# 2. 嵌套列表创建数组
data2 = [[1,2,3,4], [5,6,7,8]]
arr2 = np.array(data2)

# 3. 指定数据类型,创建数组
arr3 = np.array([1.2 ,2.3 ,3.4, 4.6], dtype=np.float32)

# 4. 同3一样,'f4'表示数据类型的类型代号,也就是名称简写
arr4 = np.array([1.2, 2, 3, 4], dtype='f4')

# 5. 数组的属性,shape返回各维度的大小的元组,dtype返回说明数组类型的对象,ndim返回维度有多少。
arr2.shape, arr2.dtype, arr2.ndim

# 6. 强制类型转换
int_arr3 = arr3.astype(np.int32)


创建数组的其他常用函数


# 1. zeros创建一个全0数组
zero1 = np.zeros(10)
zero2 = np.zeros((3, 4))

# 2. ones创建一个全1数组
one1 = np.ones(10)

# 3. empty未初始化一个数组,相当于占用内存,等待被赋值
empty1 = np.empty((2, 3, 4))

# 4. arange是Python内置函数range的数组版
value = np.arange(10)

# 5. asarray将输入转换为ndarray,如果输入本身是ndarray就不就行复制
arr5 = np.asarray(arr4)

# 6. ones_like以另一个数组为参数,根据其shape和dtype创建一个全1数组
one2 = np.ones_like(arr4)

# 7. random的randn函数创建数组,生成一些正态分布的随机数据
data = np.random.randn(3, 2)


2. 数组的索引和切片功能


arr = np.arange(10)

# 1. 索引
arr[5]

# 2. 切片
arr[5: 8]

# 3. 切片赋值,当将一个标量赋值给一个切片时,该值会自动传播到整个选区
arr[5: 8] = 12

# 4. 数组的切片是原始数组的视图,也就是数据不会被复制,视图上的任何修改都会直接反映到源数组上
arr_slice = arr[5: 8]
arr_slice[1] = 2345
print(arr_slice)
print(arr)

# 5. 如果想要ndarray切片的副本而非视图,就需要明确进行复制操作
arr_slice_copy = arr[5: 8].copy()

# 6. 二维数组的索引和切片,二维数组的索引方式。轴0作为行,轴1作为列
arr2d = np.array([[1, 2, 3, ], [4, 5, 6], [7, 8, 9]])
# 返回一个一维数组, array([7, 8, 9])
arr2d[2]
# 返回8
arr2d[2][1]
# 同上等价,用逗号隔开,也返回8
arr2d[2, 1]
# 二维切片,它是沿着第0轴切片的,也就是arr2d的前两行
arr2d[:2]
# 二维切片,它是沿着第0轴切片的,然后沿着第1轴切片,即:前两行和后两列的交叉
arr2d[:2, 1:]
# 二维切片,选取第二行的前两列
arr2d[1, :2]
# 二维切片,只用冒号代表所有行,即表示选取整个轴
arr2d[:, :2]

# 7. 布尔型索引,注:布尔索引选取的数据是创建了数据的副本,不是原始数据的视图。
name = np.array(['bob', 'jak', 'will', 'bob', 'bob', 'will', 'jak'])
data = np.random.randn(7, 4)
# 布尔类型用于数组索引,返回第1/3/4行的数据
data[name == 'bob']
# 布尔类型跟切片、索引混合使用
data[name == 'bob', 1:]
data[name == 'bob', 2]
# 选择除’bob‘以外的其他值,可以用不等于符号,也可以用~对条件进行否定
data[name != 'bob']
data[~(name == 'bob')]
# 多个布尔条件的组合,使用&(和)、|(或)之类的布尔算术运算符
mask = (name == 'bob') | (name == 'will')
data[mask]
# 例:使用布尔类型筛选数据,或赋值用法
data[data < 0]
data[data < 0] = 0


[  12 2345   12]
[ 0 1 2 3 4 12 2345 12 8 9]


# 花式索引,它是利用整数数组进行索引,注:花式索引跟切片不一样,它总是将数据复制到新数组中
arr = np.empty((8, 4))
for i in range(8):
arr[i] = i

# 1. 以特定顺序选取行子集
arr[[4, 3, 0, 6]]
# 2. 使用负数索引将从末尾开始选取行
arr[[-3, -5, -7]]
# 3. 选取列子集
arr[:, [0, 2, 3, 1]]


arr2 = np.arange(32).reshape(8, 4)
# 如果一次传入多个索引数组,它返回的是一个一维数组,其中的元素对应各个索引的元组
# 如下,选取的是(1, 0)、(5, 3)、(7, 1)、(2, 2)对应元素,可能与我们的预期不一样
arr2[[1 ,5 ,7, 2], [0, 3, 1, 2]]
# 如果我们想选取行列的子集,该怎么做呢?
arr2[[1, 5, 7, 2]][:, [0, 3, 1, 2]]


array([[ 4,  7,  5,  6],
[20, 23, 21, 22],
[28, 31, 29, 30],
[ 8, 11, 9, 10]])


3. 数组的转置与轴对换


转置是重塑的一种特殊形式,它返回的是源数据的视图。


arr = np.arange(15).reshape((3, 5))

# 1. 转置
arr.T

# 2. transpose对高维数组进行转置
arr = np.arange(16).reshape((2, 2, 4))
# 例:第一个轴和第二个轴对换,最后一个轴不变
arr.transpose((1, 0, 2))

# 3. swapaxes 函数,接受一对轴编号进行互换
# 本例子与上面的例子一样的效果输出
arr.swapaxes(0, 1)


array([[[ 0,  1,  2,  3],
[ 8, 9, 10, 11]],

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


4. 数组的运算和通用函数


通用函数(即ufunc)是一种对ndarray中的数组执行元素级运算的函数。


arr = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[0, 4, 1], [7, 2, 12]])
# 1. 简单的运算
1/arr
arr * arr
arr - arr
arr ** 0.5
arr2 > arr
# 2. 通用函数运算
# 平方根
np.sqrt(arr)
# e的指数
np.exp(arr)


x = np.random.randn(8)
y = np.random.randn(8)
# 1. 接收2个数组,返回一个结果数组的函数
# x, y 中元素级别最大的元素,maximum与fmax等同,但fmax忽略NaN
np.maximum(x, y)

# 2. 返回多个结果数组的函数
# 返回浮点数组的小数和整数部分
arr = np.random.randn(7)*5
remainder, whole_part = np.modf(arr)
# 3. out参数是就地进行操作,将计算的结果赋值给变量outer
outer = np.empty((2, 3), dtype=np.float32)
np.sqrt(arr2, out=outer)


array([[0.       , 2.       , 1.       ],
[2.6457512, 1.4142135, 3.4641016]], dtype=float32)


其他函数,如:abs/square/log10/log2/log1p/sign/ceil/floor/rint/isnan/cos/cosh/tan/tanh


其他接收两个参数的函数,如:add/subtract/multiply/mod/greater/greater_equal/less/less_equal/equal/not_equal/power


5. 利用数组进行数据处理


问题1:想要在一组值(网格型)计算函数sqrt(x^2 + y^2)


points = np.arange(-5, 5, 0.01)
# 1. meshgrid函数接受两个一维数组,产生两个二维矩阵
xs, ys = np.meshgrid(points, points)
z = np.sqrt(xs**2 + ys**2)
# 可视化这个二维数组
import matplotlib.pyplot as plt
plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2+y^2}$ for a grid of values")


Text(0.5, 1.0, 'Image plot of $\\sqrt{x^2+y^2}$ for a grid of values')



问题2:将条件逻辑表述为数组运算,如:根据条件逻辑选取x还是选取y


# 示例1
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = np.where(cond, xarr, yarr)

# 示例2
arr = np.random.randn(4, 4)
np.where(arr>0, 2, -2)

# 示例3
np.where(arr>0, 2, arr)

# 示例4,返回筛选的索引值,本例是(array([3, 4]),)
np.where(yarr>2.3)


(array([3, 4]),)


6. 数学和统计方法


整个数据或者指定某个轴的数据进行统计计算。聚合函数常见有sum/mean/std等


arr = np.random.randn(5, 4)
# 1. 所有元素的平均值
arr.mean()

# 2. 指定轴,0表示计算行的平均值,1表示计算列的平均值
arr.mean(axis=0)
arr.mean(axis=1)
# 等价方式
np.mean(arr, axis=0)
np.mean(arr, axis=1)

# 3. 累加/累成函数,产生一个中间结果组成的数组
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
arr.cumsum()

arr2 = np.arange(9).reshape(3, 3)
arr2.cumsum(axis=0)
arr2.cumprod(axis=1)

# 4. 指定轴的最大值/最小值
arr2.min(axis=1)
arr2.max(axis=0)

# 5. 指定轴的最大和最小元素的索引
arr2.argmax(axis=1)
arr2.argmin(axis=1)

# 6. 用于布尔数组的方法,布尔值会被强制转换为1(True)和0(False)
# sum经常用于对布尔数组中True值计数
arr = np.random.randn(100)
(arr>0).sum()
# 布尔数组的两个方法:any和all,any用于检查是否存在一个或者多个True,all用于检查所有值是否为True
bools = np.array([False, False, True, False])
bools.any()
bools.all()


False


7. 排序


# 1. sort方法就地排序,会修改数组本身
arr = np.random.randn(6)
arr.sort()
# 2. np.sort返回的是数组已排序副本
arr = np.random.randn(6)
np.sort(arr)
# 3. 指定轴排序
arr2 = np.random.randn(3, 6)
arr2.sort(1)


8. 唯一化和集合逻辑


np.unique用于找出数组中唯一值并返回已排序的结果,相当于Python内置代码 sorted(set(values))


# 唯一化
value = np.array([3, 3, 5, 1, 2, 2])
np.unique(value)


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


np.in1d用于测试一个数组的值在另一个数组中的成员资格,返回布尔类型数组


values = np.array([6, 0, 0, 3, 2, 5, 6])
# 测试values中的每个元素是否在列表[2, 3, 6]中
np.in1d(values, [2, 3, 6])


array([ True, False, False,  True,  True, False,  True])


数组的集合函数


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

# 1. 交集:intersect1d
np.intersect1d(x, y)

# 2. 并集: union1d(x, y)
np.union1d(x, y)

# 3. 差集:setdiff1d
np.setdiff1d(x, y)

# 4. 对称差:setxor1d,等价于 np.setdiff1d(x, y)和np.setdiff1d(y, x)的并集
np.setxor1d(x, y)


array([1, 2])


9. 数组的文件读写


np.save和np.load是读写磁盘数组的两个主要函数,默认情况以未压缩的原始二进制格式保存在扩展名.npy的文件中


# 1. 将数组写入文件
arr = np.arange(10)
np.save('some_array', arr)

# 2. 加载数组文件
np.load("some_array.npy")

# 3. 将多个数组保存在一个未压缩的文件中,数组以关键字参数的形式传入
np.savez('array_archive.npz', a=arr, b=arr*2)

# 加载多个数组存储的文件
arch = np.load("array_archive.npz")
arch['b']


array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])


10. 伪随机数生成


np.random模块是对Python内置random进行了补充,增加了一些用于高效生成多种概率分布的样本值的函数


# 1. 生成一个标准正态分布
samples = np.random.normal(4, 4)

# 2. 均匀分布
samples = np.random.randn(4, 4)

# 3. 给定上下限范围随机选取整数
samples = np.random.randint(2, 4)

# 4. 正态分布(均值0,标准差1)
samples = np.random.randn(4, 4)

# 5. 二项分布
samples = np.random.binomial(3, 0.2)

# 6.Beta分布
samples = np.random.beta(1, 2)

# 7. 在【0,1】中均匀分布
samples = np.random.uniform(2, 3)

# 8. seed确定随机数生成器的种子
np.random.seed(42)

# 9. 返回一个序列的随机排列或返回一个随机排列的范围
np.random.permutation([2, 3, 4, 5, 6])

# 10. 对一个序列就地随机排序
np.random.shuffle([2, 4, 3, 6, 10])


2. Numpy的高级应用


1. Numpy数据类型体系


ones = np.ones(10, dtype=np.uint16)
ones2 = np.ones(10, dtype=np.float32)

# 类型判断
np.issubdtype(ones.dtype, np.integer)
np.issubdtype(ones2.dtype, np.floating)
# 查看int16类型的父类
np.uint16.mro()
np.issubdtype(ones.dtype, np.number) # True


True


2. 高级数组操作


除花式索引、切片、布尔索引取子集操作之外,数组的操作方式还有很多。


  • 数组重塑


多数情况下,可以无需复制任何数据,就将数组从一个形状转换另一个形状


arr = np.arange(8)
# 默认按行排序
arr.reshape((4, 2))
# 同上一样,默认 order='C'
arr.reshape((4, 2), order='C')
# 按列排序,order='F'
arr.reshape((4, 2), order='F')

# 若参数的形状的其中一维是-1,那么它表示该维度的大小由数据本身推断而来
arr = np.arange(15)
arr.reshape((5, -1)) # 推断出形状(5,3)


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


# 数组的扁平化或散开重塑
# flatten方法,它总是返回数据的副本
# ravel方法产生的结果若与原始数据相同,则不会产生数据副本,否则是数据副本
arr = np.arange(15).reshape((5, 3))
arr.ravel() # 返回 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
arr.flatten() # 返回 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

# 同reshape类型,参数order="F"列优先,order="C"行优先,默认行优先
# 若更高的维度,则 C表示轴1会优先轴0,F表示轴0会优先轴1
arr.ravel("F") # 返回 array([ 0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14])


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


  • 数组的合并和拆分


np.concatenate可以按指定轴将一个数组组成序列连接一起


arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
# 1. 指定轴进行合并
np.concatenate([arr1, arr2], axis=0)

# 2. 同1功能一样
np.vstack((arr1, arr2)) # 0轴上合并
np.hstack((arr1, arr2)) # 1轴上合并

# 3. 将一个数组拆分多个数组
arr = np.random.randn(5, 2)
# 例子:参数[1, 3]表示按行拆分[0, 1], [1, 3], [3: ]
first, second, third = np.split(arr, [1, 3])


  • 其他合并函数:

    • row_stack,等价于 vstack,面向行的方式堆叠合并;

    • column_stack, 等价于hstack,面向列的方式堆叠合并;

    • dstack,面向深度的方式对数据进行堆叠(沿轴2)

  • 其他拆分函数:

    • hsplit: 沿着轴0拆分

    • vsplit:沿着轴1拆分

    • dsplit: 沿着轴2拆分


3. 元素的重复操作:tile和repeat


repeat会将数组中各个元素重复一定次数,从而产生一个更大的数组;


arr = np.arange(3)
arr.repeat(3) # array([0, 0, 0, 1, 1, 1, 2, 2, 2])
arr.repeat([2, 3, 4]) # array([0, 0, 1, 1, 1, 2, 2, 2, 2])


arr = np.random.randn(2, 2)
# 若没有设置轴向,则数组会被扁平化
arr.repeat(2) # 扁平化重复
arr.repeat(2, axis=0) # 轴0方向重复
arr.repeat([2, 3], axis=1) # 轴1方向重复


array([[ 0.291034  ,  0.291034  , -0.63555974, -0.63555974, -0.63555974],
[-1.02155219, -1.02155219, -0.16175539, -0.16175539, -0.16175539]])


tile功能是沿着指定轴堆叠数组的副本,类似于铺瓷砖;


arr = np.arange(4)
np.tile(arr, 2) # array([0, 1, 2, 3, 0, 1, 2, 3])


arr = np.array([[1, 2], [2, 3]])
# 第二个参数是瓷砖的数量,对于标量,如2,瓷砖是水平铺设
np.tile(arr, 2) # array([[1, 2, 1, 2], [2, 3, 2, 3]])
# 对于元组,如(2,4),瓷砖是垂直铺设的数量和水平铺设的数量
np.tile(arr, (2, 4))


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


4. 花式索引的等价函数:take和put


arr = np.arange(10)*10

# 1. 花式索引表示
arr[[7, 1, 2, 6]]
# 2. 等价1
arr.take([7, 1, 2, 6])
# 3. 赋值操作,等价 arr[[7, 1, 2, 6]]=42
arr.put([7, 1, 2, 6], 42)
# 赋值操作,等价 arr[[7, 1, 2, 6]]=[42, 43, 44, 45]
arr.put([7, 1, 2, 6], [42, 43, 44, 45])

arr = np.random.randn(4, 4)
arr.take([1, 2], axis=1).take([2, 3], axis=0)


array([[ 0.17555329, -0.30928855],
[-0.36782572, 1.27373362]])


5. 广播


当两个数组的形状不相同时,可扩充较小数组中的元素来适配较大数组的形状,这种机制叫作广播


广播的原则:广播主要发生在两种情况,一种情况是如果两个张量的维数不相等,但是它们的后缘维度的轴长相符。所谓后缘维度(trailing dimension)是指,从末尾开始算起的维度。另外一种情况是,如果两个张量的后缘维度不同,则有一方的长度为1。


# 1. 例子
# 以下的后缘维度是3
arr = np.random.randn(4, 3)
# 以下的后缘维度是3
arr.mean(0)
# 广播
demeaned = arr - arr.mean(0)


# 2. 例子2
# 数组维度(4,3)的后缘维度是3
arr = np.random.randn(4, 3)
# 数组维度(4,)的后缘维度是4
arr.mean(1)
# 以下不能广播,会报错ValueError
# arr - arr.mean(1)
# 根据广播原则,修改其中一方的后缘维度是1即可
arr - arr.mean(1).reshape(4, 1)



# 3. 例子3
# 后缘维度是(4,2)
arr = np.random.randn(3, 4, 2)
# 后缘维度是(3, 2)
arr.mean(1)
# 以下不能广播,会报错ValueError
# arr - arr.mean(1)
# 如果两个张量的后缘维度不同,则有一方的长度为1,np.newaxis为广播添加一个长度为1的新轴
demeaned = arr - arr.mean(1)[:, np.newaxis, :]


注:数组形状(3,4,2)和(4,2)的维度是不相同的,前者为3维,后者为2维。但是它们后缘维度的轴长相同,都为(4,2),所以可以沿着0轴进行广播。同样,还有一些例子:(4,2,3)和(2,3)是兼容的,(4,2,3)还和(3)是兼容的,后者需要在两个轴上面进行扩展。


同时(4,6)和(1,6)、(3,5,6)和(1,5,6)、(3,1,6)、(3,5,1),后面三个分别会沿着0轴,1轴,2轴进行广播,(3,5,6)和(1,6)也是兼容的。


6. ufunc高级应用


reduce接受一个数组参数,通过一系列的二元运算对其值进行聚合(可指明轴向)。例如:可以用np.add.reduce对数组中各个元素进行求和


# 1. 例子1
arr = np.arange(10).reshape(2, 5)
# 默认是第0轴上
np.add.reduce(arr)
# 指定在第1轴
np.add.reduce(arr, axis=1)


# 2. 例子2
arr = np.arange(10).reshape(2, 5)
# logical_and.reduce跟all方法等价
np.logical_and.reduce(arr)


array([False,  True,  True,  True,  True])


accumulate跟reduce的关系就像cumsum跟sum的关系那样,产生一个跟原数组大小相同的中间”累计“值数组。


arr = np.arange(15).reshape((3, 5))
np.add.accumulate(arr, axis=1)


array([[ 0,  1,  3,  6, 10],
[ 5, 11, 18, 26, 35],
[10, 21, 33, 46, 60]])


outer用于计算两个数组的叉集


arr = np.arange(3)
np.multiply.outer(arr, arr)

np.add.outer(arr, arr)

np.subtract.outer(x, y)


array([[-2, -3, -4],
[-1, -2, -3],
[ 0, -1, -2]])


reduceat用于计算”局部约简“,其实就是一个对数据各切片进行聚合的groupby运算。


arr = np.arange(10)
# 数组切片分为:[0:5], [5:8], [8:]
np.add.reduceat(arr, [0, 5, 8])


array([10, 18, 17])


7. 在有序数组中查找元素


np.searchsorted是一个在有序数组中执行二分查找的数组方法,只要将值插入到它返回的那个位置就能维持数组的有序性。


arr = np.array([0, 1, 7, 12, 15])
arr.searchsorted(9) # 返回3

arr.searchsorted([0, 8, 11, 16]) # array([0, 3, 3, 5])

# 例:假设我们有一个数组,还有一个表示面元边界的数组,我们希望用它将数组拆分开
data = np.floor(np.random.uniform(0, 10000, 50))
bins = np.array([0, 100, 1000, 5000, 10000])
labels = bins.searchsorted(data)
import pandas as pd
pd.Series(data).groupby(labels).mean()


1      46.000000
2 535.000000
3 3167.083333
4 7361.750000
dtype: float64


8. 间接排序:argsort和lexsort


values = np.array([5, 0, 1, 3, 2])
indexer = values.argsort() # 返回array([1, 2, 4, 3, 0])
values[indexer]

# 例子:对数组的第一行进行排序
arr = np.random.randn(3, 5)
arr[0] = values
arr[:, arr[0].argsort()]

# lexsort可以一次性对多个键数组执行间接排序
first_name = np.array(["Bob", "Jane", "Steve", "Bob"])
last_name = np.array(["Jones", "Arnold", "Arnold", "Coda"])
sorter = np.lexsort((first_name, last_name)) # 注:键的应用顺序是从最后一个传入算起的,即last_name先于firt_name被应用
zip(last_name[sorter], first_name[sorter])


<zip at 0x7fb7169d7600>


9. 线性代数


线性代数,如矩阵乘法、矩阵分解、行列式以及其他方阵运算。


from numpy import linalg as lg
x = np.random.randn(2, 3)
y = np.random.randn(3, 2)
a = np.dot(x, y) # 矩阵乘法

arr = np.random.randn(3, 3)
b = arr.dot(lg.inv(arr)) # lg.inv矩阵的逆
q, r = lg.qr(arr) # QR分解
s, v, d = lg.svd(arr) # 奇异值分解(SVD)


后记:

由于工作等原因,利用零零散散的时间终于把Numpy的知识点梳理完毕,主要参考《利用Python进行数据分析》第二版教程,自己尝试代码的编写重新实现和理解,相对来说不难,只要用起来就很容易上手。最后说一下心得吧,学习写文章还是真的很费时间,可能有些东西一看就懂,但写起来就要从头写起,另外整合成文章格式也并不容易。本公众号目的是专注个人提升与学习,所以也希望更多时间利用在自我提升上,不希望为了发表文章浪费大量精力,后期我会改变一下方法,最后感谢一下我老婆,每天晚上都带娃睡觉,使我有时间在书房学习,继续努力。

文章转载自谭西路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论