【问题标题】:How to convert a 'for' loop into a matricial expression for a list of lists using python3?如何使用 python3 将“for”循环转换为列表列表的矩阵表达式?
【发布时间】:2017-06-25 22:38:28
【问题描述】:

我需要将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]], []]

是否可以使用矩阵表达式来代替 for 循环,例如 M[indices].append(toSave[range(4)])

【问题讨论】:

  • indices 在这里做什么?

标签: python numpy matrix


【解决方案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:])]

【讨论】:

  • 谢谢迪瓦卡。我知道使用slicing 会更快,但我会尽量避免任何类型的for 循环。只有一个问题:如何使用刚刚创建的矩阵更新以前的 M 列表:图像 M 不为空但等于我们计算的最后一个:M=[[array([0, 2])], [array([0, 0]), array([0, 1]), array([0, 3])], []],具有相同的索引和循环解决方案我会获取M=[[array([0, 2]), array([0, 2])], [array([0, 0]), array([0, 1]), array([0, 3]), array([0, 0]), array([0, 1]), array([0, 3])], []]
  • @GiuseppeAngora 如果您尝试更新已创建的M 列表,请不要使用此方法。在使用 for 循环的问题上,鉴于每个索引处的子列表数量参差不齐,因此无法避免使用 for 循环。只有在进入循环之前完成大部分事情,你才能拥有比其他人更有效地做事情的“更好的 for 循环”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
相关资源
最近更新 更多