簡體   English   中英

如何在 Python Scipy 稀疏 COO(坐標格式)矩陣中保留顯式零值?

[英]How to Retain Expicit Zero Values in a Python Scipy Sparse COO (Coordinate Format) Matrix?

我創建了一個 COO 矩陣,數據數組中的值為零。 當我查詢新的 COO 矩陣數據數組時,我可以在數組中看到那些零值。 但是,我無法獲得那些零值的索引。 我使用 nonzero() 方法來檢索索引,並且缺少那些零值的索引。 有誰知道如何獲得這些零值的索引? 如果不是,這是 COO 代碼中的錯誤嗎?

下面是重現問題的示例代碼。 最后的斷言是假的,因為值的數量是七個,但只有六個非零索引。 我知道非零顯然不包括我的零值,但有沒有辦法使用另一種類似的方法來獲得明確的零值?

sparse_simple = sp.coo_matrix(
    [
        [1.1, 0, 1.1],
        [0, 1.1, 4.1],
        [1.1, 4.1, 1.1]
    ]
)

sparse_simple_data = sparse_simple.data
sparse_simple_nz = sparse_simple.nonzero()
sparse_simple_data[1] = 0
(n_rows, n_cols) = sparse_simple.shape
sparse_simple_with_explicit_close_to_zero = sp.coo_matrix(
    (sparse_simple_data, (sparse_simple_nz[0], sparse_simple_nz[1])),
    shape=(n_rows, n_cols)
)
num_explicit_vals = len(sparse_simple_with_explicit_close_to_zero.data)
nz_idcs = sparse_simple_with_explicit_close_to_zero.nonzero()
num_nzs = len(nz_idcs[0])

assert num_explicit_vals == num_nzs

我試圖在 Scipy sparse arrays 的文檔中找到另一種方法來提取值的索引,包括非零值,但沒有找到任何東西。

我有一個修復程序,但這有點麻煩。 我只是將一個小數字添加到數據數組中的所有 nvalues,然后這個“工作”。

通過將其添加到上面創建 COO 矩陣的行中,這將識別“零”值,該值現在是一個非常小的值。 我用這個修復了我的代碼,但我不喜歡它。

sparse_simple.data += 0.1e-09
In [1]: import numpy as np
In [2]: from scipy import sparse

您的樣本矩陣:

In [3]: sparse_simple = sparse.coo_matrix(
   ...:     [
   ...:         [1.1, 0, 1.1],
   ...:         [0, 1.1, 4.1],
   ...:         [1.1, 4.1, 1.1]
   ...:     ]
   ...: )

In [4]: sparse_simple
Out[4]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 7 stored elements in COOrdinate format>

您已經擺弄了data屬性; 這是其他的:

In [5]: sparse_simple.data, sparse_simple.row, sparse_simple.col
Out[5]: 
(array([1.1, 1.1, 1.1, 4.1, 1.1, 4.1, 1.1]),
 array([0, 0, 1, 1, 2, 2, 2], dtype=int32),
 array([0, 2, 1, 2, 0, 1, 2], dtype=int32))

添加你的“顯式”0; 不改變矩陣的“稀疏性”:

In [6]: sparse_simple.data[1] = 0; sparse_simple
Out[6]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 7 stored elements in COOrdinate format>

In [7]: sparse_simple.A
Out[7]: 
array([[1.1, 0. , 0. ],
       [0. , 1.1, 4.1],
       [1.1, 4.1, 1.1]])

但是nonzero ,顧名思義,不包括這個明確的 0:

In [8]: sparse_simple.nonzero()
Out[8]: 
(array([0, 1, 1, 2, 2, 2], dtype=int32),
 array([0, 1, 2, 0, 1, 2], dtype=int32))

如果我們查看代碼,我們就會明白為什么:

In [9]: sparse_simple.nonzero??
Signature: sparse_simple.nonzero()
Source:   
    def nonzero(self):
        """nonzero indices

        Returns a tuple of arrays (row,col) containing the indices
        of the non-zero elements of the matrix.
        """

        # convert to COOrdinate format
        A = self.tocoo()
        nz_mask = A.data != 0
        return (A.row[nz_mask], A.col[nz_mask])

它以“原始”coo 屬性開始,但刪除了所有“顯式”0——所以我們只得到非零值,而不是非零值加上“顯式”0。

稀疏矩陣也有一個就地方法來“清除”顯式 0:

In [24]: sparse_simple.eliminate_zeros??
Signature: sparse_simple.eliminate_zeros()
Source:   
    def eliminate_zeros(self):
        """Remove zero entries from the matrix

        This is an *in place* operation
        """
        mask = self.data != 0
        self.data = self.data[mask]
        self.row = self.row[mask]
        self.col = self.col[mask]

我已經看到它更多地用於csr格式。 改變這種格式的稀疏性相對昂貴,所以創建顯式 0 的操作不會在它們自己之后“清理”; 我們可以之后再做。

請注意coo格式不能被索引,例如sparse_simple[0,1]返回錯誤。 csr格式可以。

因此,雖然可以創建帶有顯式 0 的矩陣,但這些矩陣以其他方式被視為異常。

暫無
暫無

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

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