如何避免以下代码中的嵌套for循环,而例如使用map函数?
import numpy as np
A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
n = len(A[0])
B = np.zeros((n,n))
for i in range(n):
for j in range(n):
B[j,i] = min(A[:,i]/A[:,j])
答案 0 :(得分:1)
我认为map()
不适合解决此问题,因为您期望的结果是嵌套而不是拼合的。这比仅使用列表理解来获得所需的结果还要冗长一些。这是初始化B
的一种更简洁的方法。
B = np.array([np.min(A.T/r, axis=1) for r in A.T])
此操作遍历A
的每一列(A.T
的每一行)并计算广播的除法A.T/r
。 Numpy能够优化这一点,远远超出了原始循环所能做的。然后,np.min()
的使用会比我们能够更快地计算出我们刚沿着每行(由于参数axis=1
而行而不是列)计算出的那个矩阵的最小值内置min()
进行内部矢量化处理。
如果您确实想映射某些内容,@ MartijnPieters指出您可以将itertools与itertools.product(range(len(A[0])), repeat=2)
配合使用以实现相同的索引对。否则,您可以使用生成器((r, s) for r in A.T for s in A.T)
来获取成对的行而不是成对的索引。无论哪种情况,您都可以在可迭代的对象上应用map()
,但是仍然必须以某种方式嵌套结果才能正确初始化B
。
注意:这可能不是您期望的结果。 A
的元素默认情况下为整数(请注意,您使用的是3
而不是3.
)。当您将A
的整数元素相除时,您将再次获得整数。在您的代码中,np.zeros()
将这些整数强制转换为浮点数的事实使部分混淆,但是无论如何数学都是错误的。要解决此问题,请在构造A
时传递一个附加参数:
A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], float)