在Python中命名维度?

5

有一件事情我很希望能够实现,那就是在 Python 的数组中为维度命名。例如,我有一个具有 3 个维度的 numpy 数组,并且经常需要沿着特定的维度进行求和。

因此,我可以使用一个 ndarray a

sum(a, axis=2)

如果我的相关尺寸是最后一个,但我想使它“位置无关”,即用户可以提供任何数组,只要他指定“此尺寸为“DI”“(例如,对于“感兴趣的尺寸”). 因此,基本上我想能够编写以下内容:
sum(a, axis="DI")

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


4
不需要问候和感谢。事实上,您甚至可以在此处查看曾经(现在可能已经改进)用于删除它们的正则表达式。 - DSM
我能想到的最好方法是维护一个字典,其中包含从名称到轴编号的映射。或者使用嵌套字典,在底部使用数组,但这可能比它值得的麻烦多了(据我所知,在numpy中也不太合适)。 - Henry Keiter
1
你真的需要将 DI 定义为字符串吗?如果你在代码中将 DI = 2,那么你就可以使用 np.sum(a, axis=DI)... - jorgeca
2个回答

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 现在已经非常接近原帖中所要求的内容了。


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

简单而优雅!你们中的几个人提出了这个解决方案,我也应该想到它。是的,@M456的想法不错,但我会选择最简单的一种!谢谢! - François Laenen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接