2

Python で R 配列に似たもの、またはそれよりも優れたものを使用したいと考えています。R 配列は、名前 (文字列) に基づいてテンソルを直接サブセット化できるようにする、dimnames 属性を持つテンソルのようなオブジェクトです。numpy の再配列では列名を使用でき、pandas では 2 次元配列の柔軟かつ効率的なサブセット化が可能です。名前を使用して ndarrays をスライスおよびサブセット化するのと同様の操作を可能にする Python の何か (または、Python でハッシュ可能で不変のオブジェクト) はありますか?

4

1 に答える 1

3

文字列のリストからインデックスへのこの簡単で汚いマッピングはどうですか? 呼び出し可能なクラスで表記をクリーンアップできます。

def make_dimnames(names):
    return [{n:i for i,n in enumerate(name)} for name in names]
def foo(d, *args):
    return [d[x] for x in args]

A = np.arange(9).reshape(3,3)
dimnames = [('x','y','z'),('a','b','c')]
Adims = make_dimnames(dimnames)
A[foo(Adims[0],'x','z'),foo(Adims[1],'b')]  # A[[0,2],[1]]
A[foo(Adims[0],'x','z'),slice(*foo(Adims[1],'b','c'))]  # A[[0,2],slice(1,2)]

それともR、dimnames でも​​っと重要なことをしますか?

クラスは構文を少し圧縮します。

class bar(object):
    def __init__(self,dimnames):
        self.dd = {n:i for i,n in enumerate(dimnames)}
    def __call__(self,*args):
        return [self.dd[x] for x in args]
    def __getitem__(self,key):
        return self.dd[key]
d0, d1 = bar(['x','y','z']), bar(['a','b','c'])
A[d0('x','z'),slice(*d1('a','c'))]

http://docs.scipy.org/doc/numpy/user/basics.subclassing.html ndarray をサブクラス化し、属性 (dinnames など) を追加する簡単な例を示します。おそらく、その属性を使用するようにインデックスを拡張することは難しいことではありません。

__getitem__inの使用に着想を得てnumpy/index_tricks、インデックス作成を一般化しました。

class DimNames(object):
    def __init__(self, dimnames):
        self.dd = [{n:i for i,n in enumerate(names)} for names in dimnames]
    def __getitem__(self,key):
        # print key
        if isinstance(key, tuple):
            return tuple([self.parse_key(key, self.dd[i]) for i,key in enumerate(key)])
        else:
            return self.parse_key(key, self.dd[0])
    def parse_key(self,key, dd):
        if key is None:
            return key
        if isinstance(key,int):
            return key
        if isinstance(key,str):
            return dd[key]
        if isinstance(key,tuple):
            return tuple([self.parse_key(k, dd) for k in key])
        if isinstance(key,list):
            return [self.parse_key(k, dd) for k in key]
        if isinstance(key,slice):
            return slice(self.parse_key(key.start, dd),
                         self.parse_key(key.stop, dd),
                         self.parse_key(key.step, dd))
        raise KeyError

dd = DimNames([['x','y','z'], ['a','b','c']])

print A[dd['x']]              # A[0]
print A[dd['x','c']]          # A[0,2]
print A[dd['x':'z':2]]        # A[0:2:2]
print A[dd[['x','z'],:]]      # A[[0,2],:]
print A[dd[['x','y'],'b':]]   # A[[0,1], 1:]
print A[dd[:'z', :2]]         # A[:2,:2]

さらなるステップは、 をサブクラス化し、属性としてA追加ddし、その を変更して__getitem__、表記を に単純化することだと思いますA[['x','z'],'b':]

于 2014-04-05T21:29:59.223 に答える