簡體   English   中英

Python中二維數組的對數

[英]Logarithm of two dimensional array in Python

我有一個名為矩陣的二維數組數組。 其中的每個矩陣的尺寸為1000 x 1000 ,由正值組成。 現在我想記錄所有矩陣中的所有值(0除外)。
如何在python中輕松完成此操作?
我有以下代碼可以做我想要的,但是知道Python這可以更簡單:

newMatrices = []
for matrix in matrices:
    newMaxtrix = []
    for row in matrix:
        newRow = []
        for value in row:
            if value > 0:
                newRow.append(np.log(value))
            else:
                newRow.append(value)
        newMaxtrix.append(newRow)
    newMatrices.append(newMaxtrix)

您可以將其轉換為numpy數組並使用numpy.log來計算值。

對於0值,結果將為-Inf 之后,您可以將其轉換回列表並將-Inf替換為0

或者你可以使用where的numpy的

例:

res = where(arr!= 0, log2(arr), 0)

它將忽略所有零元素。

雖然@Amadan的答案當然是正確的(並且更短/更優雅),但在你的情況下它可能不是最有效的(當然取決於輸入),因為np.where()將生成一個整數索引對於每個匹配值。 更有效的方法是生成布爾掩碼。 這有兩個優點:(1)它通常具有更高的內存效率(2) []運算符在掩碼上通常比在整數列表上更快。

為了說明這一點,我在玩具輸入上重新實現了基於np.where()和基於掩碼的解決方案(但具有正確的大小)。 我還包括一個基於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的值的注釋

使用numpy另一種選擇:

arr = np.ndarray((1000,1000))
np.log.at(arr, np.nonzero(arr))

就像...一樣簡單

import numpy as np
newMatrices = [np.where(matrix != 0, np.log(matrix), 0) for matrix in matrices]

無需擔心行和列,numpy負責處理它。 當理解足夠可讀時,無需在for循環中顯式迭代矩陣。

編輯:我剛注意到OP有log ,而不是log2 對於解決方案的形狀並不重要(盡管可能非常重要但沒有得到錯誤的答案:P)

如同@ R.yan所說,你可以嘗試這樣的事情。

import numpy as np

newMatrices = []
for matrix in matrices:
    newMaxtrix = []
    for row in matrix:
        newRow = []
        for value in row:
            if value > 0:
                newRow.append(np.log(value))
            else:
                newRow.append(value)
        newMaxtrix.append(newRow)
    newMatrices.append(newMaxtrix)

newArray = np.asarray(newMatrices)
logVal = np.log(newArray)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM