假设我有一个由列表列表组成的矩阵,如下所示:
>>> 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
>>> LoLa=np.array(LoL)
使用numpy,我可以得到这个矩阵的子矩阵,如下所示:
>>> LoLa[1:4,2:5] array([[2, 3, 4], [2, 3, 4], [2, 3, 4]])
我可以像这样在纯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中)将任意矩阵切片为子矩阵?
In [74]: [row[2:5] for row in LoL[1:4]] Out[74]: [[2, 3, 4], [2, 3, 4], [2, 3, 4]]
您还可以通过定义以下子类来模仿NumPy的语法list:
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子类不会赢得任何速度测试:
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
但是速度并不是一切-有时可读性更重要。