提高自定义表类中python列表操作和比较的速度

2024-10-01 09:41:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用下面的类创建一个表,我需要找到一种方法,不仅使它更快,而且使与它的交互更快:

class Table(object):
    """a three dimensional table object"""
    def __init__(self, xsize=1, ysize=1, zsize=1):
        self.xsize = xsize
        self.ysize = ysize
        self.zsize = zsize
        self.data = [0] * (xsize * ysize * zsize)

    def __getitem__(self, key):
        x, y, z = self.__extractIndices(key)
        return self.data[x + self.xsize * (y + self.ysize * z)]

    def __setitem__(self, key, value):
        x, y, z = self.__extractIndices(key)
        self.data[x + self.xsize * (y + self.ysize * z)] = value

    def __extractIndices(self, key):
        x = y = z = 0
        if (self.ysize > 1):
            if (self.zsize > 1):
                if len(key) != 3:
                    raise IndexError
                else:
                    x, y, z = key
            elif len(key) != 2:
                raise IndexError
            else:
                x, y = key
        elif not isinstance(key, int):
            raise IndexError
        else:
            x = key
        return (x, y, z)

    def resize(self, xsize=1, ysize=1, zsize=1):
        """resize the table preserving data"""
        oldlist = list(self.data)
        self.data = [0] * (xsize * ysize * zsize)
        self.xsize = xsize
        self.ysize = ysize
        self.zsize = zsize
        for i in range(0, oldlist):
            self.data[1] = oldlist[i]

在这一点上,我需要找出两个列表中的数据是否与每个z的值相等 所以我就这么做了。self.data和{}是上面的表类实例

^{pr2}$

显然,这是我能想到的最慢的方法,考虑到我正在比较的一些表的大小为200*200*3=120000个条目。我需要这个尽快。在

我考虑过重写上面的比较,将一个z的所有条目切分如下

tempflag = False
#layer 1
slicepoint1 = 0
slicepoint2 = self.data.xsize * self.data.ysize * 1
data1 = self.data.data[slicepoint1:slicepoint2]
data2 = self.map.data.data[slicepoint1:slicepoint2]
if data1 != data2:
    tempflag = True
    layer1flag = True
#layer 2
slicepoint1 = self.data.xsize * self.data.ysize * 1
slicepoint2 = self.data.xsize * self.data.ysize * 2
data1 = self.data.data[slicepoint1:slicepoint2]
data2 = self.map.data.data[slicepoint1:slicepoint2]
if data1 != data2:
    tempflag = True
    layer2flag = True
#layer 3
slicepoint1 = self.data.xsize * self.data.ysize * 2
slicepoint2 = self.data.xsize * self.data.ysize * 3
data1 = self.data.data[slicepoint1:slicepoint2]
data2 = self.map.data.data[slicepoint1:slicepoint2]
if data1 != data2:
    tempflag = True
    layer3flag = True
#copy the data if it changed
if tempflag:
    self.data = copy.deepcopy(self.map.data)
    previewflag = True

虽然这看起来会更快,但似乎仍有很大的改进。例如,不能使用numpy在Table类中构建数据列表吗?在

我需要这个类和这个检查尽可能快地运行

如果使用numpy可以让我非常快速地遍历表,这样我就可以将其中的数据用于blit操作来构建一个tilemap

Ido需要保留table类的通用接口,尤其是表数据存储在自我数据在

总之,使用numpy可以提高操作速度吗?如果是这样,我该怎么做?在


Tags: 数据keyselftruedataifdefdata1
2条回答

这绝对是纽比的申请!它不仅可以加快代码的速度,还可以大大简化代码,因为索引和比较已经由NumPy处理。你将不得不阅读一些教程来学习NumPy只是一些提示,让你在这种情况下。在

通常,我只需要从numpy.ndarray派生来定义一个自定义数组类,但是您声明您确实需要data属性,这与numpy.ndarray.data冲突。你的课简化为

class Table(object):
    def __init__(self, xsize=1, ysize=1, zsize=1):
        self.data = numpy.zeros((xsize, ysize, zsize))

    def __getitem__(self, key):
        return self.data[key]

    def __setitem__(self, key, value):
        self.data[key] = value

    def resize(self, xsize=1, ysize=1, zsize=1):
        # This only works for increasing the size of the data,
        # but is easy do adapt to other cases
        newdata = numpy.zeros((xsize, ysize, zsize))
        shape = self.data.shape
        newdata[:shape[0], :shape[1], :shape[2]] = self.data
        self.data = newdata

比较代码简化为

^{pr2}$

而且速度也会快得多!在

我想是的,通过使用numpy你可能会获得很多速度。在

你也可以做长方形切片,但你也可以做长方形切片:

>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a[:2,1:]
array([[2, 3],
       [5, 6]])

我不知道你想完成什么,但你也可以简单地比较numpy数组元素:

^{pr2}$

如果你有更多的问题,请尽管评论。在

相关问题 更多 >