我不熟悉列表理解,但我想用列表理解来计算bray-curtis的不同点。不同之处如下所示:
def bray(x):
bray_diss = np.zeros((x.shape[0], x.shape[0]))
for i in range(0, bray_diss.shape[0]):
bray_diss[i,i] = 0
for j in range(i+1, bray_diss.shape[0]):
l1_diff = abs(x[i,:] - x[j,:])
l1_sum = x[i,:] + x[j,:] + 1
bray_diss[i,j] = l1_diff.sum() / l1_sum.sum()
bray_diss[j,i] = bray_diss[i,j]
return bray_diss
我试着这样做:
def bray(x):
[[((abs(x[i,:] - x[j,:])).sum() / (x[i,:] + x[j,:] + 1).sum()) for j in range(0, x.shape[0])] for i in range(0, x.shape[0])]
如果没有成功,我就搞不懂怎么了!此外,在第一个实现中,没有对所有矩阵行值执行第二个循环以节省计算时间,如何能够使用列表理解来执行它?你知道吗
谢谢!你知道吗
你不会从列表中得到任何东西。。。除了更好的理解列表! 你必须理解的是,列表理解是一个功能概念。我不会详细介绍函数式编程, 但是你必须记住函数式编程禁止副作用。举个例子:
最后一行是副作用:修改
my_matrix
的状态。相反,没有副作用的版本可以:您没有“创建然后分配”序列:您通过在每个位置声明值来创建矩阵。更准确地说,要创建矩阵:
(i,j)
时,你不能用它来声明另一个单元格的值(例如(j,i)
)(如果以后需要变换矩阵,则必须重新创建它。这就是为什么这种方法在时间和空间上都很昂贵。)
现在,看看你的代码。在编写列表理解时,一个好的经验法则是使用辅助函数,因为它们有助于清理代码(这里我们不尝试创建一行):
那更干净。下一步是什么?在上面的代码中,您选择迭代大于
i
的j
,并同时设置两个值。但是在列表理解中,你不能选择单元格:列表理解为每个单元格提供坐标,你必须声明值。你知道吗首先,让我们尝试每次迭代只设置一个值,即使用两个循环:
这样更好。第二,我们需要给矩阵的每个单元格赋值,而不仅仅是在单元格前加上零并选择不想更新的单元格:
一个简短的版本是,使用Python的“伪三元条件运算符”:
现在我们可以将其转化为列表理解:
如果我没说错的话,更简单的是(最终版本):
请注意,这个版本可能比你的版本慢,但在我看来,矩阵的构建方式更容易掌握。你知道吗
相关问题 更多 >
编程相关推荐