【发布时间】:2017-01-15 15:27:39
【问题描述】:
我得到一个(标准化的)稀疏邻接矩阵和相应矩阵行的标签列表。由于某些节点已被另一个清理功能删除,因此矩阵中有一些包含 NaN 的行。我想找到这些行并删除它们以及它们各自的标签。这是我写的函数:
def sanitize_nan_rows(adj, labels):
# convert to numpy array and keep dimension
adj = np.array(adj, ndmin=2)
for i, row in enumerate(adj):
# check if row all nans
if np.all(np.isnan(row)):
# print("Removing nan row label in %s" % i)
# remove row index from labels
del labels[i]
# remove all nan rows
adj = adj[~np.all(np.isnan(adj), axis=1)]
# return sanitized adj and labels_clean
return adj, labels
labels 是一个简单的 Python 列表,adj 的类型为 <class 'scipy.sparse.lil.lil_matrix'>(包含 <class 'numpy.float64'> 类型的元素),它们都是
adj, labels = nx.attr_sparse_matrix(infected, normalized=True)
执行时出现以下错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-503-8a404b58eaa9> in <module>()
----> 1 adj, labels = sanitize_nans(adj, labels)
<ipython-input-502-ead99efec677> in sanitize_nans(adj, labels)
6 for i, row in enumerate(adj):
7 # check if row all nans
----> 8 if np.all(np.isnan(row)):
9 print("Removing nan row label in %s" % i)
10 # remove row index from labels
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
所以我认为 SciPy NaN 与 numpy NaN 不同。之后,我尝试将稀疏矩阵转换为 numpy 数组(冒着淹没我的 RAM 的风险,因为矩阵有大约 40k 行和列)。但是,运行它时,错误保持不变。 np.array() 调用似乎只是包装了稀疏矩阵并没有转换它,因为 for 循环内的 type(row) 仍然输出 <class 'scipy.sparse.lil.lil_matrix'>
所以我的问题是如何解决这个问题以及是否有更好的方法来完成工作。我对 numpy 和 scipy(在 networkx 中使用)相当陌生,所以我很感激解释。谢谢!
编辑:将转换更改为hpaulj 建议的转换后,我收到了 MemoryError:
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
<ipython-input-519-8a404b58eaa9> in <module>()
----> 1 adj, labels = sanitize_nans(adj, labels)
<ipython-input-518-44201f4ff35c> in sanitize_nans(adj, labels)
1 def sanitize_nans(adj, labels):
----> 2 adj = adj.toarray()
3
4 for i, row in enumerate(adj):
5 # check if row all nans
/usr/lib/python3/dist-packages/scipy/sparse/lil.py in toarray(self, order, out)
348 def toarray(self, order=None, out=None):
349 """See the docstring for `spmatrix.toarray`."""
--> 350 d = self._process_toarray_args(order, out)
351 for i, row in enumerate(self.rows):
352 for pos, j in enumerate(row):
/usr/lib/python3/dist-packages/scipy/sparse/base.py in_process_toarray_args(self, order, out)
697 return out
698 else:
--> 699 return np.zeros(self.shape, dtype=self.dtype, order=order)
700
701
MemoryError:
所以显然我必须坚持使用稀疏矩阵来节省 RAM。
【问题讨论】:
-
稀疏矩阵不是密集数组。查看
adj.data和adj.rows。对于lil矩阵,这些是列表的对象数组,数组的每行一对子列表。 -
adj.A或adj.toarray()产生一个数组 -
感谢您的快速回复!我根据您提出的更改和我的结果编辑了问题。 (我只是把转换线改成
adj = adj.toarray()) -
是
adjNaN 的整行还是该行的非零值?一个大的稀疏矩阵可能有数千列,但每行只有数百个非零条目。一行中的大多数值将为 0(并且在稀疏数据库中不存在)。
标签: python numpy scipy sparse-matrix networkx