How to implement __getitem__ such that it can process the input args and then pass them into the underlying numpy array?

huangapple go评论58阅读模式
英文:

How to implement __getitem__ such that it can process the input args and then pass them into the underlying numpy array?

问题

只返回翻译好的部分:

让 A 成为一个简单的 Python 类,它具有一个成员 self._mat,该成员是一个 NumPy 数组。
A 的构造函数接受一个整数 n,创建一个内部的 n x n 的零数组,并将其保存为私有成员 self._mat。

如何实现 __getitem__ 以便首先预处理传递给 __getitem__ 的参数(例如,将某些字符串(例如序列化的 ID)映射为从零开始的整数索引),然后将它们传递到内部的 NumPy 数组 self._mat 中,以使它的处理方式与类的用户简单地将处理后的参数直接传递到内部的 NumPy 数组一样?

A 的一个示例(糟糕的)实现如下:

class A():
     def __init__(self, n: int=3):
         self._mat = np.zeros(shape=[n, n])
     def __getitem__(self, val):
         # 此实现是错误的,不传递解释...
         val = _process_val(val)  # 我如何正确地处理这一点,以便查看可能的多索引中的每个索引的内部元素?
         return self._mat[val]

示例用法:

a = A(n=4)
print(a[0], a[0, 1], a[(0, 1)], a[:, 1:2])
# 假设字符串 'deadbeef' 被转换为整数 0
print(a['deadbeef'], a['deadbeef', 1], a(('deadbeef', 1)], a[:, 'deadbeef':2])

(注意:这个翻译保留了原始代码中的注释和代码示例。)

英文:

Let A be a simple python class that has one member self._mat which is a numpy array.
The constructor of A gets an integer n and creates an inner n by n zeros numpy array and saves it as the private member self._mat.

How can I implement __getitem__ such that I can first preprocess the arguments passed to __getitem__ (for instance map certain strings, such as serialized IDs, into zero-based integer indices), and then pass them into the inner numpy array self._mat such that it will be handled the same way as if the user of the class simply passed the processed arguments straight into the inner numpy array?

An example (bad) implementation of A looks like this:

class A():
     def __init__(self, n: int=3):
         self._mat = np.zeros(shape=[n, n])
     def __getitem__(self, val):
         # This implementation is wrong and doesn't pass interpretation...
         val = _process_val(val)  # How do I process this correctly such that I look at the inner elements of each index in the POSSIBLE multi-index as well?
         return self._mat[val]

Example usages:

a = A(n=4)
print(a[0], a[0, 1], a[(0, 1)], a[:, 1:2])
# Lets say that the string 'deadbeef' is cast onto the integer 0
print(a['deadbeef'], a['deadbeef', 1], a[('deadbeef', 1)], a[:, 'deadbeef':2])

答案1

得分: 4

基本思想可以通过递归来解决 - 改变你想要的所有元素,同时保持相同的参数结构。

import numpy as np

def process_arg(arg):
    if isinstance(arg, str):
        if arg == "deadbeef":
            return 0
    if isinstance(arg, tuple):
        return tuple(process_arg(a) for a in arg)
    else:
        return arg

class A():
    def __init__(self, n: int=3):
        self._mat = np.zeros(shape=[n, n])
    def __getitem__(self, arg):
        arg = process_arg(arg)
        return self._mat.__getitem__(arg)

a = A(n=4)
print(a[0], a[0, 1], a[(0, 1)], a[:, 1:2])
print(a['deadbeef'], a['deadbeef', 1], a(('deadbeef', 1)))

处理类似于 a[:, 'deadbeef':2] 中的切片部分,我将留给您作为练习。

英文:

Basic idea can be solved with recursion - changing all the elements you want, while keeping same general structure of an argument.

import numpy as np

def process_arg(arg):
    if isinstance(arg, str):
        if arg == "deadbeef":
            return 0
    if isinstance(arg, tuple):
        return tuple(process_arg(a) for a in arg)
    else:
        return arg


class A():
    def __init__(self, n: int=3):
        self._mat = np.zeros(shape=[n, n])
    def __getitem__(self, arg):
        arg = process_arg(arg)
        return self._mat.__getitem__(arg)

a = A(n=4)
print(a[0], a[0, 1], a[(0, 1)], a[:, 1:2])
print(a['deadbeef'], a['deadbeef', 1], a[('deadbeef', 1)])

Handling slices as in a[:, 'deadbeef':2] I'll leave as an exercise to you.

huangapple
  • 本文由 发表于 2023年5月24日 21:38:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324174.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定