4

我正在寻找一个数据结构来表示一些遗传数据。该数据可以表示为一个大小列表n,其中每个条目还有一个“遗传位置”,它是一个介于 0 和 1 之间的实数。为了使命名清晰,我将列表中的位置id称为遗传位置gpos。我实现这个的方式是作为一个类

class Coords(object):

    def __init__(self, *args, **kwargs):
        self.f = list(*args, **kwargs)
        self.r = dict()
        for i,e in enumerate(self.f):
            self.r[e] = i

    def __setitem__(self,x,y):
        self.f.__setitem__(x,y)
        self.r.__setitem__(y,x)

    def __getitem__(self,x):
        return self.f.__getitem__(x)

    def __len__(self):
        return self.f.__len__()

现在,我有两个问题。第一个是 self.r 的索引是浮点数,这显然是个坏主意。我正在考虑将它们转换为字符串(具有固定位数),但有更好的主意吗?我遇到的另一个问题是我想通过 实现访问条目gpos,因此,例如,如果我想访问gpos0.2 到 0.4 之间的所有内容,我希望能够使用

import numpy as np
Coords(np.arange(1,0,-.1))
c.r[0.2:0.4]

有没有一种简单的方法来定义它?我正在考虑id使用二进制搜索找到正确的开始和结束位置,然后self.f使用这些 id 进行访问,但是有没有办法实现上述语法?

4

2 回答 2

5

当您使用切片索引对象时,Python 会使用slice您提供的输入创建一个对象。例如,如果你这样做c[0.2:0.4],那么传递给的参数c.__getitem__将是slice(0.2, 0.4)__getitem__所以你可以在你的方法中有这样的代码:

def __getitem__(self, x):
    if isinstance(x, slice):
        start = x.start
        stop = x.stop
        step = x.step
        # Do whatever you want to do to define your return
    ...

如果您不想在Coords对象上而是在self.r字典中使用这种花哨的索引,我认为最简单的方法是创建 aFancyIndexDict的子类dict,修改其__getitem__方法,然后self.r是 a FancyIndexDict,而不是 a dict

于 2013-08-28T02:51:26.540 回答
3

如果您知道您的gpos值将(或可以)始终按排序顺序存储,那么我绝对建议您使用二进制搜索来完成此任务。您可以利用数组语法和searchsortednumpy的内置实现:

>>> gpos_vals = np.linspace(0, 1, 11)
>>> gpos_vals
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])
>>> lo, hi = gpos_vals.searchsorted([0.22, 0.52])
>>> lo, hi
(3, 6)
>>> gpos_vals[lo:hi]
array([ 0.3,  0.4,  0.5])

我认为这很好地避免了您指出的关于使用浮点数作为字典键的问题,这可能是有问题的。

您还可以将此答案与 Jaime 的答案结合起来,并创建一个在 custom 中查找切片的类,__getitem__然后将切片参数传递给searchsorted我的代码片段:

class GeneticPositions(object):
    def __init__(self, gpos_values):
        self.gpos_values = np.asarray(gpos_values)

    def __getitem__(self, x):
        if isinstance(x, slice):
            lo, hi = self.gpos_values.searchsorted(
                [x.start or 0, x.stop or 1])
            return self.gpos_values[lo:hi]
        return self.gpos_values[x]
于 2013-08-28T04:56:53.020 回答