2013-03-27 25 views
9

假设我有一个像这样一个列表的列表组成的矩阵:列表(没有numpy的)的列表的子矩阵

>>> LoL=[list(range(10)) for i in range(10)] 
>>> LoL 
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] 

假设,另外,我有称为相同结构的numpy的矩阵LoLa

>>> LoLa=np.array(LoL) 

使用numpy的,我能得到这个矩阵的小矩阵是这样的:

>>> LoLa[1:4,2:5] 
array([[2, 3, 4], 
     [2, 3, 4], 
     [2, 3, 4]]) 

我可以replic吃纯Python像这样的numpy的矩阵片段:

>>> r=(1,4) 
>>> s=(2,5) 
>>> [LoL[i][s[0]:s[1]] for i in range(len(LoL))][r[0]:r[1]] 
[[2, 3, 4], [2, 3, 4], [2, 3, 4]] 

这是不是世界上最容易读,也不是最有效的:-)

问:是否有一个更简单的方法(在纯Python)将任意矩阵切片为子矩阵?

回答

11
In [74]: [row[2:5] for row in LoL[1:4]] 
Out[74]: [[2, 3, 4], [2, 3, 4], [2, 3, 4]] 

你也可以模仿NumPy的语法定义的list一个子类:

class LoL(list): 
    def __init__(self, *args): 
     list.__init__(self, *args) 
    def __getitem__(self, item): 
     try: 
      return list.__getitem__(self, item) 
     except TypeError: 
      rows, cols = item 
      return [row[cols] for row in self[rows]] 

lol = LoL([list(range(10)) for i in range(10)]) 
print(lol[1:4, 2:5]) 

也产生

[[2, 3, 4], [2, 3, 4], [2, 3, 4]] 

使用LoL子不会赢得任何速度测试:

In [85]: %timeit [row[2:5] for row in x[1:4]] 
1000000 loops, best of 3: 538 ns per loop 
In [82]: %timeit lol[1:4, 2:5] 
100000 loops, best of 3: 3.07 us per loop 

但速度并非一切 - 有时可读性更重要。

+0

第二部分*完全*偷走了我的答案! :-))+1 – dawg 2013-03-27 02:21:11

+1

干杯,@drewk;下一个是你的:) – unutbu 2013-03-27 02:25:01

5

首先,你可以直接使用slice对象,这有点帮助与可读性和性能都:

r = slice(1,4) 
s = slice(2,5) 
[LoL[i][s] for i in range(len(LoL))[r]] 

如果你只是遍历列表中,列出了直接,你可以写如:

[row[s] for row in LoL[r]] 
0

我不知道它更容易,但让我扔的想法表:

from itertools import product 
r = (1+1, 4+1) 
s = (2+1, 5+1) 
array = [LoL[i][j] for i,j in product(range(*r), range(*s))] 

这是您想要的子矩阵的扁平版本。

1

执行此,

子阵列= [[垫[i] [j]对于在范围Ĵ(index1之间索引2)]其中i在范围(INDEX3,index4)]

的子阵列将原始大矩阵的矩形(如果index3 == index1和index2 == index4)块。