Python np矩阵的列表理解

Python np矩阵的列表理解,python,numpy,Python,Numpy,我有两个np矩阵,其中一个我正试图标准化。我知道,一般来说,列表理解比for循环快,所以我尝试将double for循环转换为列表表达式 # normalize the rows and columns of A by B for i in range(1,q+1): for j in range(1,q+1): A[i-1,j-1] = A[i-1,j-1] / (B[i-1] / B[j-1]) 到目前为止,我得到的是: A = np.asarray([A/(

我有两个np矩阵,其中一个我正试图标准化。我知道,一般来说,列表理解比for循环快,所以我尝试将double for循环转换为列表表达式

# normalize the rows and columns of A by B
 for i in range(1,q+1):
     for j in range(1,q+1):
         A[i-1,j-1] = A[i-1,j-1] / (B[i-1] / B[j-1])
到目前为止,我得到的是:

A = np.asarray([A/(B[i-1]/B[j-1]) for i, j in zip(range(1,q+1), range(1,q+1))])
但我认为我采取了错误的方法,因为我没有看到任何明显的时差


任何帮助都将不胜感激。

首先,如果你真的是指
np.matrix
,请停止使用
np.matrix
。它有各种令人讨厌的不兼容性,而且由于矩阵乘法的
@
已经存在,它的角色已经过时了。即使您被困在没有
@
的Python版本上,使用
dot
方法和正常的Ndarray仍然比处理
np.matrix
要好

您不应该对NumPy数组使用任何类型的Python级迭代构造,无论是
循环还是列表理解,除非您确定没有更好的选项。假设A是2D,B是1D,形状分别为
(q,q)
(q,)
,在这种情况下,您应该做的是

A *= B
A /= B[:, np.newaxis]

A
的操作。这将允许NumPy直接在数组的底层数据缓冲区上执行C级别的迭代,而不必创建包装器对象并对每个操作执行动态调度。

首先,如果您确实是指
np.matrix
,请停止使用
np.matrix
。它有各种令人讨厌的不兼容性,而且由于矩阵乘法的
@
已经存在,它的角色已经过时了。即使您被困在没有
@
的Python版本上,使用
dot
方法和正常的Ndarray仍然比处理
np.matrix
要好

您不应该对NumPy数组使用任何类型的Python级迭代构造,无论是
循环还是列表理解,除非您确定没有更好的选项。假设A是2D,B是1D,形状分别为
(q,q)
(q,)
,在这种情况下,您应该做的是

A *= B
A /= B[:, np.newaxis]

A
的操作。这将允许NumPy直接在数组的底层数据缓冲区上执行C级迭代,而不必创建包装器对象并对每个操作执行动态调度。

为什么您认为列表理解通常比循环快?假设你在理解中实际使用了for循环。除非你真的没有更好的选择,否则你不应该使用列表理解或
for
循环和NumPy数组。思想列表理解通常比for循环快一点点,因为它不必在每个数组上查找列表及其append方法迭代。通常不是很明显。您尝试执行的最大问题是,您使用的是普通Python,而不是向量化的
numpy
操作。专注于这一点,而不是使用列表式理解。在双循环中,您在原地修改
a
。在理解中,从列表中创建一个新数组。这抵消了理解过程中可能节省的时间。把理解看作是一种简化的列表附加循环方式。为什么你认为列表理解通常比循环快?假设你在理解中实际使用了for循环。除非你真的没有更好的选择,否则你不应该使用列表理解或
for
循环和NumPy数组。思想列表理解通常比for循环快一点点,因为它不必在每个数组上查找列表及其append方法迭代。通常不是很明显。您尝试执行的最大问题是,您使用的是普通Python,而不是向量化的
numpy
操作。专注于这一点,而不是使用列表式理解。在双循环中,您在原地修改
a
。在理解中,从列表中创建一个新数组。这抵消了理解过程中可能节省的时间。将理解看作是执行列表附加循环的一种简化方式。