具有命名字段访问的python张量
我想在Python中使用类似于——或优于——R数组的东西。R数组是具有dimnames属性的类张量对象,该属性允许直接基于名称(字符串)对张量进行子集。在numpy中,重新排列允许列名,并允许灵活高效地对二维数组进行子集设置。Python中是否有类似的操作,例如通过使用名称(或者更好的是,Python中可散列且不可变的对象)对Ndarray进行切片和子集分割?这种从字符串列表到索引的快速而肮脏的映射怎么样?您可以使用可调用类来清理符号具有命名字段访问的python张量,python,r,numpy,multidimensional-array,recarray,Python,R,Numpy,Multidimensional Array,Recarray,我想在Python中使用类似于——或优于——R数组的东西。R数组是具有dimnames属性的类张量对象,该属性允许直接基于名称(字符串)对张量进行子集。在numpy中,重新排列允许列名,并允许灵活高效地对二维数组进行子集设置。Python中是否有类似的操作,例如通过使用名称(或者更好的是,Python中可散列且不可变的对象)对Ndarray进行切片和子集分割?这种从字符串列表到索引的快速而肮脏的映射怎么样?您可以使用可调用类来清理符号 def make_dimnames(names):
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
对DIMName做了更重要的事情
类稍微压缩语法:
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'))]
子类ndarray,带有添加属性(可以是dinnames)的简单示例。大概扩展索引以使用该属性并不难
受numpy/index\u技巧
中使用\uuu getitem\uuuuuuuuuu
的启发,我概括了索引:
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
添加为属性,并更改其\uuuu getitem\uuuuu
,将符号简化为A[[['x','z'],'b':]
这就是您要寻找的:否。pandas.panel只需在一个宽矩阵上返回一个长的表示(或者用类似于行话的重塑方式,它会融化)。我正在寻找一个真正的带有命名轴标签的张量对象。事实上,你的第二个例子是做R做不到的事情。但是,对于大多数示例来说,R的语法更简洁(我无法用Python重现,这是我的错),并且不需要携带Adims对象;例如,A[['x'、'z']、'b']或A[['x'、'z']、['b']]。我的第二个担忧是,当堆叠张量时,R会处理属性,而这种方法不会。我的第三个担忧是,我反对重新发明轮子,而宁愿使用已经建立的东西。我为\uuuuu getitem\uuuuu
添加了更多功能,因此它直接处理切片、元组等。它试图复制existingnumpy
getitem,在字符串情况下添加字典查找。