2013-03-27 3 views
9

私はそうのようなリストのリストから構成されるマトリックスを有すると仮定:サブマトリックス

>>> 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]] 

はIと呼ばれる同じ構造のnumpyの行列を有すること、また、想定LoLa

numpyのを使用して
>>> LoLa=np.array(LoL) 

、私はこのように、この行列の部分行列を得ることができます:

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

私はreplicすることができます

>>> 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でnumpyの行列のスライスを食べましたPython)を使って任意の行列を部分行列としてスライスしますか?

答えて

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

またlistのサブクラスを定義することによって模倣numpyのの構文ができます

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]) 

LoLサブクラスは任意の速度のテストを獲得しません使用

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

を生み出します:

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 

スピードはすべてではありません - 時には可読性が重要です。

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

そして、あなただけの直接リスト・オブ・リストを反復た場合、あなたはそれを書くことができます:読みやすさとパフォーマンスの両方でビットを助け、あなたが直接sliceオブジェクトを使用することができるものについては

+0

2番目の部分*は完全に私の答えを盗んだ! :-))+1 – dawg

+1

乾杯、@drewk;次はあなたのものです:) – unutbu

5

、よう:

[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]は範囲内のiについての範囲のJ(index1の、INDEX2)](index3、index4)のために]

サブマットになります元の大きな行列の長方形(正方形if index3 == index1とindex2 == index4)の塊。