我需要使用矩阵形式将for
循环转换为表达式。我有一个列表列表,一个索引列表,以及一个名为' toSave'的形状矩阵(4,2):
import numpy as np
M = [list() for i in range(3)]
indices= [1,1,0,1]
toSave = np.array([[0, 0],
[0, 1],
[0, 2],
[0, 3]])
索引中的每个索引i
我想在索引中保存与索引i
的位置对应的行:
for n, i in enumerate(indices):
M[i].append(toSave[n])
结果是:
M=[[[0, 2]], [[0, 0], [0, 1], [0, 3]], []]
是否可以使用matricial表达式来使用for
循环,某些内容为M[indices].append(toSave[range(4)])
?
答案 0 :(得分:1)
这是一种方法 -
sidx = np.argsort(indices)
s_indx = np.take(indices, sidx)
split_idx = np.flatnonzero(s_indx[1:] != s_indx[:-1])+1
out = np.split(toSave[sidx], split_idx, axis=0)
示例运行 -
# Given inputs
In [67]: M=[[] for i in range(3)]
...: indices= [1,1,0,1]
...: toSave=np.array([[0, 0],
...: [0, 1],
...: [0, 2],
...: [0, 3]])
...:
# Using loopy solution
In [68]: for n, i in enumerate(indices):
...: M[i].append(toSave[n])
...:
In [69]: M
Out[69]: [[array([0, 2])], [array([0, 0]), array([0, 1]), array([0, 3])], []]
# Using proposed solution
In [70]: out
Out[70]:
[array([[0, 2]]), array([[0, 0],
[0, 1],
[0, 3]])]
提升绩效
更快捷的方法是避免np.split
并与slicing
进行分割,就像这样 -
sorted_toSave = toSave[sidx]
idx = np.concatenate(( [0], split_idx, [toSave.shape[0]] ))
out = [sorted_toSave[i:j] for i,j in zip(idx[:-1],idx[1:])]