3 回答
TA貢獻1844條經驗 獲得超8個贊
您可以將其轉換為 numpy 數組并用于numpy.log計算值。
對于 0 值,結果將為-Inf。之后,您可以將其轉換回列表并將其替換為-Inf0
或者你可以where在 numpy 中使用
例子:
res = where(arr!= 0, log2(arr), 0)
它將忽略所有零元素。
TA貢獻1777條經驗 獲得超3個贊
雖然@Amadan 的答案肯定是正確的(而且更短/更優雅),但在您的情況下它可能不是最有效的(當然,這取決于輸入),因為np.where()將為每個匹配值生成一個整數索引。更有效的方法是生成布爾掩碼。這有兩個優點:(1) 通常內存效率更高 (2)[]運算符在掩碼上通常比在整數列表上更快。
為了說明這一點,我np.where()在玩具輸入(但具有正確的大?。┥现匦聦崿F了基于 -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未定義的值歸零的注釋
添加回答
舉報
