Python Numpy和矩阵的相关面试问题

liftword3个月前 (02-24)技术文章38

通常,数据科学家被要求在Python中执行简单的矩阵运算,这应该很简单,但许多人会偏离正轨。

本文将介绍面试中经常出现的4个Numpy/matrix问题,并用Python编写代码。


问题1:

给定4x4 Numpy矩阵,如何反转矩阵?

#?步骤0:构造一个4*4?Numpy矩阵
import?numpy?as?np
matrix?=?np.arange(1,17).reshape(4,4)
print(matrix)
[[?1??2??3??4]
?[?5??6??7??8]
?[?9?10?11?12]
?[13?14?15?16]]

旁注,np.arange(1,17) 返回一个Numpy数组,并*reshape(4,4)生成一个44矩阵。

#?步骤1:展平numpy数组
matrix_flat?=?matrix.flatten()
matrix_flat
array([?1,??2,??3,??4,??5,??6,??7,??8,??9,?10,?11,?12,?13,?14,?15,?16])

有两种方法可以根据数据类型展平矩阵。对于Numpy数组,我们使用np.array.flatten() ;对于非数组矩阵,我们用matrix.ravel(). 请试一试。

#?步骤2:将元素读入一个新的矩阵
matrix_reversed?=?matrix_flat[::-1]
matrix_reversed
array([16,?15,?14,?13,?12,?11,?10,??9,??8,??7,??6,??5,??4,??3,??2,??1])

展平后,我们从最后一个元素开始向后读取矩阵。

#?步骤3:?将矩阵重塑为4*4矩阵
matrix_reversed.reshape(4,4)

最后,我们重塑矩阵并将其转换回4*4矩阵,如下所示:

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

Numpy数组或矩阵的独特属性是,必须在反转它之前将其展平,并且有两种方法取决于数据格式(是否为Numpy)。


问题2:

两个矩阵如何相乘?

这类问题可能很棘手!

两个矩阵?是不是numpy?

解决方案在很大程度上取决于它所引用的数据类型。总的来说,有两种解决方案:用于Numpy数组的dot方法和用于非数组的循环方法。

解决方案1:Numpy数组

#?步骤1:?Numpy数组
A?=?np.arange(9).reshape(3,3)
B?=?np.arange(10,19).reshape(3,3)
A
B
#?A
array([[0,?1,?2],
???????[3,?4,?5],
???????[6,?7,?8]])
???????
#?B
array([[10,?11,?12],
???????[13,?14,?15],
???????[16,?17,?18]])
???????
#?步骤2:?dot?方法?
result?=?A.dot(B)
print(result)
[[?45??48??51]
?[162?174?186]
?[279?300?321]]

dot方法很容易解决Numpy数组的乘法问题,但我怀疑面试问题不会这么容易。

所以,对非数组做乘法题的可能性更大。

解决方案2:非数组

#?步骤0:构造两个矩阵。
X?=?[
????[1,2,3],
????[2,3,4,],
????[4,3,2]
]

Y?=?[
????[2,3,4],
????[3,4,6],
????[2,3,5]
]

Python没有matrix的内置数据类型,我们使用列表的列表(嵌套列表)。

#?步骤1:创建一个零矩阵来存储结果
Z?=?[
????[0,0,0],
????[0,0,0],
????[0,0,0]
]

创建空矩阵的原因是将乘法结果存储在下面的嵌套for循环中。

#?步骤2:嵌套for循环
#?在X的行上迭代;?len(X)返回行数
for?i?in?range(len(X)):
?????
????#?在Y的列上迭代;?len(Y[0])返回列数
????for?j?in?range(len(Y[0])):
????????
????????#?迭代Y的行
????????for?k?in?range(len(Y)):
????????????
????????????Z[i][j]?+=?X[i][k]*Y[k][j]
????????
Z
[[14,?20,?31],?[21,?30,?46],?[21,?30,?44]]

让我们解开嵌套for循环:

  1. for i in range(len(X)):返回行数;
  2. for j in range(len(Y[0])):返回Y的列数。旁注:我们使用Y[0]访问矩阵列,使用Y访问矩阵行;
  3. for k in range(len(Y)):迭代Y的行;
  4. Z[i][j]+=X[i][k]*Y[k][j]:按元素乘法的和填充Z中的值。

回想一下,两个矩阵的序列相乘:X的第一行中的元素与Y的第一列中的元素相乘再相加。重复这个过程直到结束。

上面的嵌套循环简单地遵循与我们通常所做的相同的计算矩阵乘法的过程。


问题3:

如何转置矩阵?

同样,有多种解决方案取决于是否允许你使用Numpy。

解决方案1:嵌套for循环(不要使用Numpy)

#?步骤0:创建矩阵
X?=?[
????[12,7],
????[1,2],
????[3,4]
]

#?步骤1:空列表
transpose?=?[
????[0,0,0],
????[0,0,0]
]
#步骤2:嵌套for循环
#?行上迭代
for?i?in?range(len(X)):
????
????#?列上迭代:?#?len(transpose)?=?len(X[0])
????for?j?in?range(len(transpose)):?
????????
????????#?替换
????????transpose[j][i]?=?X[i][j]
????????
for?r?in?transpose:?
????print(r)
[12,?1,?3]
[7,?2,?4]

解决方案2:对元组列表使用zip(不要使用Numpy)

#?步骤1:创建元组列表
matrix?=?[(1,2,3),(4,5,6),(7,8,9),(10,11,12)]#?元组列表
matrix
[(1,?2,?3),?(4,?5,?6),?(7,?8,?9),?(10,?11,?12)]

我们使用一个元组列表来创建一个矩阵。

#第二步:解压和压缩成一行
#?通过*解压
#?通过zip压缩
matrix_transpose?=?zip(*matrix)

for?i?in?matrix_transpose:
????print(i)
(1,?4,?7,?10)
(2,?5,?8,?11)
(3,?6,?9,?12)

解决方案3:使用Numpy数组

3.1 np.transpose()

X?=?[
????[12,7],
????[1,2],
????[3,4]
]

#?3.1?np.transpose()
import?numpy?as?np

transpose?=?np.transpose(X)
print(transpose)

如果我们能使用Numpy,一行就可以完成任务。

3.2 np.array.T

matrix_array?=?np.array(X)

matrix_array.T
array([[12,??1,??3],
???????[?7,??2,??4]])

或者,我们可以将矩阵(list)更改为Numpy数组并使用array.T。


问题4:

如何将两个Numpy矩阵相加?

同样,有两种解决方案取决于我们是否可以使用Numpy。

解决方案1:np.array()

X?=?[[12,7,3],
????[4?,5,6],
????[7?,8,9]]

Y?=?[[5,8,1],
????[6,7,3],
????[4,5,9]]
????
import?numpy?as?np?
X_np?=?np.array(X)
Y_np?=?np.array(Y)

result?=?X_np?+?Y_np
print(result)
[[17?15?4]
[10?12?9]
[11?13?18]]

Numpy可以轻松地处理元素添加。

解决方案2:普通矩阵的嵌套for循环

result?=?np.zeros((3,3))

#?行的迭代
for?i?in?range(len(X)):

????#?列的迭代
????for?j?in?range(len(X[0])):
????????result[i][j]?=?X[i][j]+Y[i][j]
????????
for?r?in?result:?
????print(r)
[17.?15.??4.]
[10.?12.??9.]
[11.?13.?18.]

代码是不言而喻的,我们已经在上面的问题中涵盖了它们。

另一方面,这个问题有两种不同的说法。

4.1如何垂直堆叠矩阵?

X?=?[[12,7,3],
????[4?,5,6],
????[7?,8,9]]

Y?=?[[5,8,1],
????[6,7,3],
????[4,5,9]]

np.vstack((X,Y))
array([[12,??7,??3],
???????[?4,??5,??6],
???????[?7,??8,??9],
???????[?5,??8,??1],
???????[?6,??7,??3],
???????[?4,??5,??9]])

4.2如何水平堆叠矩阵?

#?水平堆叠
X?=?[[12,7,3],
????[4?,5,6],
????[7?,8,9]]

Y?=?[[5,8,1],
????[6,7,3],
????[4,5,9]]

np.hstack((X,Y))
array([[12,??7,??3,??5,??8,??1],
???????[?4,??5,??6,??6,??7,??3],
???????[?7,??8,??9,??4,??5,??9]])

请参阅Github以获取完整的Python代码:https://github.com/LeihuaYe/Matrix_in_Python


备注

  • 在面试过程中保持良好的沟通。
  • 询问澄清问题和限制条件。例如: 能用Numpy数组吗?
  • 在试图反转矩阵之前先将其展平。
  • 嵌套for循环很有用。试着理解每一行是如何工作的。

相关文章

NumPy线性代数教程:轻松掌握矩阵运算

线性代数是数据科学、机器学习和工程领域的基石。而NumPy作为Python中最强大的科学计算库之一,也提供了丰富的线性代数功能,能够帮助我们高效地进行矩阵运算。今天的内容会需要一些大学线性代数基础,但...

仅用 10 行 Python 代码,搞定 10 种数学运算!

【CSDN 编者按】在如今这个 AI 飞速发展的时代,Python 以其简洁、易读的语法和强大的表现力,深受程序员和科学家的喜爱。本文将展示在仅仅 10 行代码内,Python 如何实现复杂的数学运算...

如何在 Python 中制作矩阵:详细指南

什么是矩阵?在深入研究之前,让我们了解一下矩阵是什么:它是一个按行和列排列的数字的矩形数组。在 Python 中,我们通常使用嵌套列表来表示矩阵,其中每个内部列表代表一行。使用列表创建基本矩阵让我们从...

学习Numpy,看这篇文章就够啦

导读:在数据分析当中,Python用到最多的第三方库就是Numpy。本文内容是「大数据DT」内容合伙人王皓阅读学习《Python 3智能数据分析快速入门》过后的思考和补充,结合这本书一起学习,效果更佳...

资料 | Python数据分析基础教程:NumPy学习指南(中文第2版)

下载地址:https://www.yanxishe.com/resourceDetail/2300?from=leiphonecolumn_res0907内容简介 · · · · · ·NumPy是一...

使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析

在现代数据分析领域,时间序列数据的处理和预测一直是一个具有挑战性的问题。随着物联网设备、金融交易系统和工业传感器的普及,我们面临着越来越多的高维时间序列数据。这些数据不仅维度高,而且往往包含复杂的时间...