代码之家  ›  专栏  ›  技术社区  ›  ignorance

更改numpy array子类中的“getitem”和“setitem”的行为

  •  2
  • ignorance  · 技术社区  · 6 年前

    Numpy arrays can be efficiently subclassed 但是我想修改 __getitem__ __setitem__ 因此,它们可以接受一个日期时间范围,同时保留最大数量的内置机器,如操作、cumsum等。这可以用 __array_ufunc__ ?

    在他们的 example , the numpy.ufunc.at 方法被重写。

    这可以用来修改numpy数组的get/set行为吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   a_guest    6 年前

    你可以实现 __getitem__ __setitem__ 处理特定的情况(使用日期时间对象)并将 super().__{get|set}item__ 在其他情况下。这样剩下的功能 ndarray 保留下来。例如:

    from datetime import date
    import numpy as np
    
    class A(np.ndarray):
        def __array_finalize__(self, obj):
            if obj is not None:
                obj.start_date = date.today()
    
        def __getitem__(self, item):
            if isinstance(item, slice) and isinstance(item.start, date) and isinstance(item.stop, date):
                return super().__getitem__(slice((item.start - self.start_date).days,
                                                 (item.stop - self.start_date).days,
                                                 item.step))
            return super().__getitem__(item)
    
    a = A((10,), buffer=np.arange(10), dtype=int)
    print(a[1:8])
    print(a[date(2019, 1, 22):date(2019, 1, 29):2])
    print(np.cumsum(a))
    print(np.add.outer(a, a))
    

    输出:

    [1 2 3 4 5 6 7]
    [1 3 5 7]
    [ 0  1  3  6 10 15 21 28 36 45]
    [[ 0  1  2  3  4  5  6  7  8  9]
     [ 1  2  3  4  5  6  7  8  9 10]
     [ 2  3  4  5  6  7  8  9 10 11]
     [ 3  4  5  6  7  8  9 10 11 12]
     [ 4  5  6  7  8  9 10 11 12 13]
     [ 5  6  7  8  9 10 11 12 13 14]
     [ 6  7  8  9 10 11 12 13 14 15]
     [ 7  8  9 10 11 12 13 14 15 16]
     [ 8  9 10 11 12 13 14 15 16 17]
     [ 9 10 11 12 13 14 15 16 17 18]]