我有一段代码,但是我想提高性能。我的代码是:
lis = []
for i in range(6):
for j in range(6):
for k in range(6):
for l in range(6):
lis[i][j] += matrix1[k][l] * (2 * matrix2[i][j][k][l] - matrix2[i][k][j][l])
print(lis)
matrix2是4维np数组,而matrix1是2d数组。
我想通过使用np.tensordot(matrix1,matrix2)加快此代码的速度,但是后来我迷路了。
您可以只使用jit编译器
您的解决方案一点也不差。我唯一更改的是索引和变量循环范围。如果您有numpy数组和过多的循环,则可以使用编译器(Numba),这确实很简单。
import numba as nb
import numpy as np
#The function is compiled only at the first call (with using same datatypes)
@nb.njit(cache=True) #set cache to false if copying the function to a command window
def almost_your_solution(matrix1,matrix2):
lis = np.zeros(matrix1.shape,np.float64)
for i in range(matrix2.shape[0]):
for j in range(matrix2.shape[1]):
for k in range(matrix2.shape[2]):
for l in range(matrix2.shape[3]):
lis[i,j] += matrix1[k,l] * (2 * matrix2[i,j,k,l] - matrix2[i,k,j,l])
return lis
关于代码的简单性,与上面显示的解决方案相比,我更希望使用hpaulj的einsum解决方案。我认为,tensordot解决方案不是那么容易理解。但这是一个品味问题。
性能比较
我用于比较的hpaulj函数:
def hpaulj_1(matrix1,matrix2):
matrix3 = 2*matrix2-matrix2.transpose(0,2,1,3)
return np.einsum('kl,ijkl->ij', matrix1, matrix3)
def hpaulj_2(matrix1,matrix2):
matrix3 = 2*matrix2-matrix2.transpose(0,2,1,3)
(matrix1*matrix3).sum(axis=(2,3))
return np.tensordot(matrix1, matrix3, [[0,1],[2,3]])
非常短的数组给出:
matrix1=np.random.rand(6,6)
matrix2=np.random.rand(6,6,6,6)
Original solution: 2.6 ms
Compiled solution: 2.1 µs
Einsum solution: 8.3 µs
Tensordot solution: 36.7 µs
较大的数组可得出:
matrix1=np.random.rand(60,60)
matrix2=np.random.rand(60,60,60,60)
Original solution: 13,3 s
Compiled solution: 18.2 ms
Einsum solution: 115 ms
Tensordot solution: 180 ms
结论
编译将计算速度提高了大约3个数量级,并且比所有其他解决方案都快了许多。
我正在寻找一种用函数式编程方法替换嵌套foreach循环的方法。情况是这样的: 目前我的代码是这样的: 这将生成如下所示的输出: 有谁知道如何用函数式编程替代方案替换foreach代码块?
问题内容: 我正在尝试使用flatmap与Stream API进行嵌套循环,但似乎无法弄清楚。作为示例,我想重新创建以下循环: 我可以这样做,但这看起来很丑: Flatmap看起来很有希望,但是如何在外循环中访问变量? 输出: 问题答案: 您必须在阶段中创建所需的元素,例如:
我遇到了一个问题,我的程序只在的一次迭代中结束,我不确定不合逻辑的代码在哪里。 全球给予: 我复杂的嵌套从这里开始,但我不确定如何修复它,以便它迭代通过和数字for-循环: 我得到以下输出: 我从来没有得到Susie的数据,我很早就回来了,但似乎不知道在哪里。对于问题所在(甚至重构)的任何帮助/指导都将不胜感激。提前谢谢!
问题内容: 以下代码有效,但显示为冗长。 我的意图是通过itertools.product降低LOC。这是我想出的。 是否有其他方法可以使用itertools.product,以便有足够的值可解包? 问题答案: 您需要分别将迭代器的元素传递给: 顺便说一句,通过另一个调用,您可以保存另一行,跳过Python生成器的开销,并在C中完成所有工作:
在索引位置1的输入中遇到的字符串的前半部分将被替换为字符“-”使用流我们如何执行操作? 我有上面的列表,我想用我这样做的循环将每个嵌套列表值的第一个位置替换为“-” 样本输出:[[0,-],[6,-],[0,-],[6,gh],[4,ij],[0,ab],[6,cd]] 但是任何人都可以解释如何使用流来实现同样的目标
我有以下片段,我想知道是否可以用Java-Streams/Java8 API替换它,以及如何替换它