3 回答

TA贡献1844条经验 获得超8个赞
您可以将其转换为 numpy 数组并用于numpy.log
计算值。
对于 0 值,结果将为-Inf
。之后,您可以将其转换回列表并将其替换为-Inf
0
或者你可以where
在 numpy 中使用
例子:
res = where(arr!= 0, log2(arr), 0)
它将忽略所有零元素。

TA贡献1777条经验 获得超3个赞
虽然@Amadan 的答案肯定是正确的(而且更短/更优雅),但在您的情况下它可能不是最有效的(当然,这取决于输入),因为np.where()将为每个匹配值生成一个整数索引。更有效的方法是生成布尔掩码。这有两个优点:(1) 通常内存效率更高 (2)[]运算符在掩码上通常比在整数列表上更快。
为了说明这一点,我np.where()在玩具输入(但具有正确的大小)上重新实现了基于 -based 和基于掩码的解决方案。我还包含了一个np.log.at()基于 - 的解决方案,它也非常低效。
import numpy as np
def log_matrices_where(matrices):
return [np.where(matrix > 0, np.log(matrix), 0) for matrix in matrices]
def log_matrices_mask(matrices):
arr = np.array(matrices, dtype=float)
mask = arr > 0
arr[mask] = np.log(arr[mask])
arr[~mask] = 0 # if the values are always positive this is not needed
return [x for x in arr]
def log_matrices_at(matrices):
arr = np.array(matrices, dtype=float)
np.log.at(arr, arr > 0)
arr[~(arr > 0)] = 0 # if the values are always positive this is not needed
return [x for x in arr]
N = 1000
matrices = [
np.arange((N * N)).reshape((N, N)) - N
for _ in range(2)]
(一些健全性检查以确保我们在做同样的事情)
# check that the result is the same
print(all(np.all(np.isclose(x, y)) for x, y in zip(log_matrices_where(matrices), log_matrices_mask(matrices))))
# True
print(all(np.all(np.isclose(x, y)) for x, y in zip(log_matrices_where(matrices), log_matrices_at(matrices))))
# True
以及我机器上的时间:
%timeit log_matrices_where(matrices)
# 33.8 ms ± 1.13 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit log_matrices_mask(matrices)
# 11.9 ms ± 97 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit log_matrices_at(matrices)
# 153 ms ± 831 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
编辑:另外包括np.log.at()解决方案和关于将log未定义的值归零的注释
添加回答
举报