2013-03-27 43 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)塊。