获取 scipy 稀疏矩阵中每一行的前 n 项
Get top-n items of every row in a scipy sparse matrix
阅读 类似问题后,我仍然无法完全理解如何着手实施我正在寻找的解决方案。我有一个稀疏矩阵,即:
import numpy as np
from scipy import sparse
arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])
arr_csc = sparse.csc_matrix(arr)
我想有效地获取每行的前n项,而不将稀疏矩阵转换为密集矩阵。
最终结果应如下所示(假设 n=2):
top_n_arr = np.array([[0,5,3,0,0],[6,0,0,9,0],[0,0,0,6,8]])
top_n_arr_csc = sparse.csc_matrix(top_n_arr)
链接的答案有什么问题?它不适用于您的情况吗?或者你只是不明白?还是效率不够?
我打算建议找出一种方法来找到 lil
格式矩阵的一行的最高值,并逐行应用。但我只想重复我之前的回答。
好的,我之前的回答是一个开始,但缺少一些关于遍历 lol
格式的细节。这是一个开始;它可能可以清理干净。
制作数组,和一个lil
版本:
In [42]: arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])
In [43]: arr_sp=sparse.csc_matrix(arr)
In [44]: arr_ll=arr_sp.tolil()
上一个答案中的行函数:
def max_n(row_data, row_indices, n):
i = row_data.argsort()[-n:]
# i = row_data.argpartition(-n)[-n:]
top_values = row_data[i]
top_indices = row_indices[i] # do the sparse indices matter?
return top_values, top_indices, i
迭代 arr_ll
的行,应用此函数并替换元素:
In [46]: for i in range(arr_ll.shape[0]):
d,r=max_n(np.array(arr_ll.data[i]),np.array(arr_ll.rows[i]),2)[:2]
arr_ll.data[i]=d.tolist()
arr_ll.rows[i]=r.tolist()
....:
In [47]: arr_ll.data
Out[47]: array([[3, 5], [6, 9], [6, 8]], dtype=object)
In [48]: arr_ll.rows
Out[48]: array([[2, 1], [0, 3], [3, 4]], dtype=object)
In [49]: arr_ll.tocsc().A
Out[49]:
array([[0, 5, 3, 0, 0],
[6, 0, 0, 9, 0],
[0, 0, 0, 6, 8]])
在lil
格式中,数据存储在2个对象类型数组中,作为子列表,一个是数据编号,另一个是列索引。
查看稀疏矩阵的数据属性,做新的时候很方便。更改这些属性有一些风险,因为它会弄乱整个数组。但看起来 lil
格式可以像这样安全地调整。
csr
格式比 csc
格式更适合访问行。它的数据存储在 3 个数组中,data
、indices
和 indptr
。 lil
格式根据 indptr
中的信息有效地将其中的 2 个数组拆分为子列表。 csr
非常适合数学(乘法、加法等),但在更改稀疏性(将非零值变为零)时不太好。
阅读
import numpy as np
from scipy import sparse
arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])
arr_csc = sparse.csc_matrix(arr)
我想有效地获取每行的前n项,而不将稀疏矩阵转换为密集矩阵。 最终结果应如下所示(假设 n=2):
top_n_arr = np.array([[0,5,3,0,0],[6,0,0,9,0],[0,0,0,6,8]])
top_n_arr_csc = sparse.csc_matrix(top_n_arr)
链接的答案有什么问题?它不适用于您的情况吗?或者你只是不明白?还是效率不够?
我打算建议找出一种方法来找到 lil
格式矩阵的一行的最高值,并逐行应用。但我只想重复我之前的回答。
好的,我之前的回答是一个开始,但缺少一些关于遍历 lol
格式的细节。这是一个开始;它可能可以清理干净。
制作数组,和一个lil
版本:
In [42]: arr = np.array([[0,5,3,0,2],[6,0,4,9,0],[0,0,0,6,8]])
In [43]: arr_sp=sparse.csc_matrix(arr)
In [44]: arr_ll=arr_sp.tolil()
上一个答案中的行函数:
def max_n(row_data, row_indices, n):
i = row_data.argsort()[-n:]
# i = row_data.argpartition(-n)[-n:]
top_values = row_data[i]
top_indices = row_indices[i] # do the sparse indices matter?
return top_values, top_indices, i
迭代 arr_ll
的行,应用此函数并替换元素:
In [46]: for i in range(arr_ll.shape[0]):
d,r=max_n(np.array(arr_ll.data[i]),np.array(arr_ll.rows[i]),2)[:2]
arr_ll.data[i]=d.tolist()
arr_ll.rows[i]=r.tolist()
....:
In [47]: arr_ll.data
Out[47]: array([[3, 5], [6, 9], [6, 8]], dtype=object)
In [48]: arr_ll.rows
Out[48]: array([[2, 1], [0, 3], [3, 4]], dtype=object)
In [49]: arr_ll.tocsc().A
Out[49]:
array([[0, 5, 3, 0, 0],
[6, 0, 0, 9, 0],
[0, 0, 0, 6, 8]])
在lil
格式中,数据存储在2个对象类型数组中,作为子列表,一个是数据编号,另一个是列索引。
查看稀疏矩阵的数据属性,做新的时候很方便。更改这些属性有一些风险,因为它会弄乱整个数组。但看起来 lil
格式可以像这样安全地调整。
csr
格式比 csc
格式更适合访问行。它的数据存储在 3 个数组中,data
、indices
和 indptr
。 lil
格式根据 indptr
中的信息有效地将其中的 2 个数组拆分为子列表。 csr
非常适合数学(乘法、加法等),但在更改稀疏性(将非零值变为零)时不太好。