2013-05-06 62 views
4

有些东西我非常感谢,它是在python中命名数组中维的能力。例如,我有一个3维的numpy数组,我经常需要按照特定的维度对它进行求和。在python中命名维度?

所以我可以用ndarray a做:

sum(a, axis=2) 

如果我的相关尺寸是最后一个,但我想让它“独立地位”,即用户可以提供任何阵列,只要因为他指定“这个维度是”DI“”(例如,“感兴趣的维度”)。所以基本上我想能够写出:

sum(a, axis="DI") 

接近NETCDF,但我不想实现一个完整的netcdf功能。

+4

不需要问候和感谢。事实上,你甚至可以看到正是这个正则表达式(它现在可能已经被改进了)用于删除它们[这里](http://meta.stackexchange.com/a/93989/163205)。 – DSM 2013-05-06 15:55:38

+0

我能想到的最佳方式是维护一个字典,其中包含从名称到轴号的映射。要么是这样,要么在底部使用嵌套的数组,但这可能比它的价值更麻烦(而且据我所知,并不是犹太教中的犹太人)。 – 2013-05-06 16:34:17

+1

你真的需要'DI'作为一个字符串吗?如果你让'DI = 2'在你的代码中的某处,你就可以执行'np.sum(a,axis = DI)'... – jorgeca 2013-05-06 19:35:41

回答

3

@ M456的想法是聪明的,但如果你有多个阵列相同的命名方案,我认为简单的解决办法是只使用字典:

axes = { 'DA': 0, 'DB':1 } 
a.sum(axes['DA']) 

甚至只是变量:

DA, DB, DC = range(3) 
a.sum(DA) 

如果它应该是你最后一个(或倒数第二等)轴,只需使用-1(或-2等):

a.shape 
#(2,3,4) 

np.all(a.sum(2) == a.sum(-1)) 
#True 
np.all(a.sum(0) == a.sum(-3)) 
#True 
+0

简单而优雅!你们中有几位提出了这个解决方案,我也应该考虑一下。是的@M456的想法很好,但我会选择最简单的!谢谢! – 2013-05-07 18:24:52

3

你可以写一个薄薄的包装子类到np.ndarray。但维护维度和名称之间的对应关系可能会很棘手。

class NamedArray(np.ndarray): 
    def __new__(cls, *args, **kwargs): 
     obj = np.ndarray(args[0], **kwargs).view(cls) 
     return obj 

    def __init__(self, *args, **kwargs): 
     self.dim_names = None 
     if len(args) == 2: 
      self.dim_names = args[1] 

    def sum(self, *args, **kwargs): 
     if (self.dim_names is not None) and (type(kwargs['axis']) == str): 
      axis_name = kwargs.pop('axis') 
      axis_ind = self.dim_names.index(axis_name) 
      kwargs['axis'] = axis_ind 
     return super().sum(*args, **kwargs) 

#regular ndarray 
a = NamedArray([1,2,3], dtype=np.float32) 

#ndarray with dimension names 
b = NamedArray([1,2,3], ('d1', 'd2', 'd3'), dtype=np.float32) 

编辑: Pandas DataFrame现在是什么OP问个八九不离十的事情。