【发布时间】:2020-12-11 12:00:57
【问题描述】:
根据输入列表填充 scipy.sparse.dok_matrix 的最有效方法是什么?
dok_matrix 中的列数或行数都不知道。
行数是输入列表的长度,列数取决于输入列表中的值。
显而易见的:
def get_dok_matrix(values: List[Any]) -> scipy.sparse.dok_matrix:
max_cols = 0
datas = []
for value in values:
data = get_data(values)
datas.append(data)
if len(data) > max_cols:
max_cols = len(data)
dok_matrix = scipy.sparse.dok_matrix((len(values), max_cols))
for i, data in enumerate(datas):
for j, datum in enumerate(data):
dok_matrix[i, j] = datum
return dok_matrix
有两个 for 循环,一个嵌套 for 循环,还有许多 len() 检查。我无法想象这会非常有效。
我也考虑过:
def get_dok_matrix(values: List[Any]) -> scipy.sparse.dok_matrix:
cols = 0
dok_matrix = scipy.sparse.dok_matrix((0, 0))
for row, value in enumerate(values):
dok_matrix.resize(row + 1, cols)
data = get_data(values)
for col, datum in enumerate(data):
if col + 1 > cols:
cols = col + 1
dok_matrix.resize(row + 1, cols)
dok_matrix[row, col] = datum
return dok_matrix
这在很大程度上取决于scipy.sparse.dok_matrix.resize 的效率,我在文档中找不到。
哪一个最有效?
有没有更好的方法让我错过(也许我可以 O(1) 一次设置一整行?)?
【问题讨论】:
-
改用
coo格式怎么样? -
@hpaulj 为什么会更好?
-
dok可以迭代赋值(lil也是如此),coo是原始输入格式,如果您可以从数组或列表构建data, row, col数组,则效果很好.使用coo格式,您可以创建 3 个数组,并且只需调用一次coo_matrix(或csr)。它还负责识别最大行和列值。 -
我对矩阵的布局感到困惑。你说
values是一个列表;什么清单?你迭代values,但不要使用value。相反,您使用data = get_data(values)。每行有多少个数据值?j枚举建议您填充该行的第一个n元素。
标签: python python-3.x numpy scipy