列表列表的子矩阵(没有 numpy) [英] Sub matrix of a list of lists (without numpy)

查看:31
本文介绍了列表列表的子矩阵(没有 numpy)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个由列表组成的矩阵,如下所示:

<预><代码>>>>LoL=[list(range(10)) for i in range(10)]>>>哈哈[[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,我可以得到这个矩阵的子矩阵,如下所示:

<预><代码>>>>洛拉[1:4,2:5]数组([[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]]输出[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):尝试:返回列表.__getitem__(self, item)除了类型错误:行,列 = 项目返回 [row[cols] for row in self[rows]]大声笑 = LoL([list(range(10)) for i in range(10)])打印(大声笑 [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 个循环,最好的 3 个:每个循环 538 ns在 [82]: %timeit lol[1:4, 2:5]100000 个循环,最好的 3 个:每个循环 3.07 us

但速度不是一切——有时可读性更重要.

Suppose I have a matrix composed of a list of lists like so:

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

Assume, also, that I have a numpy matrix of the same structure called LoLa:

>>> LoLa=np.array(LoL)

Using numpy, I could get a submatrix of this matrix like this:

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

I can replicate the numpy matrix slice in pure Python like so:

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

Which is not the easiest thing in the world to read nor the most efficient :-)

Question: Is there an easier way (in pure Python) to slice an arbitrary matrix as a sub matrix?

解决方案

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


You could also mimic NumPy's syntax by defining a subclass of 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])

also yields

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

Using the LoL subclass won't win any speed tests:

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

but speed isn't everything -- sometimes readability is more important.

这篇关于列表列表的子矩阵(没有 numpy)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆