【问题标题】:How to dynamically slice array without eval?如何在没有 eval 的情况下动态切片数组?
【发布时间】:2022-01-27 08:00:52
【问题描述】:

我处于需要动态切片可变形状/尺寸数组的情况。所以我组装了一个字符串来访问它。

这在访问数据时可以正常工作。

some_data = eval("arr[:,[ci]]")

#or

some_data = eval("arr[:,[ci],:]")

#or

some_data = eval("arr[:,:,:,[ci]]")

#etc.

但是eval() 的限制使我无法使用这种方法分配

eval("arr[:,[ci]]") = some_data

有没有办法不用eval()就可以切片?

【问题讨论】:

  • 使用一些标签,因为切片不是 numpy 独有的
  • “我需要动态切片可变形状/尺寸的数组”“动态”是什么意思?你收到什么样的输入,结果需要发生什么?你能控制输入格式吗?该数据需要支持/指定哪些类型的操作?
  • "使用一些标签,因为切片不是 numpy 独有的" 你应该根据 你想要切片的东西来使用标签。 pythonnumpy 在这里有意义,假设您正在谈论一个 Numpy ndarray(这对于您显示的语法是有意义的);如果其他人必须使用pytorch 来重现问题,pytorch 是相关标记。
  • 好吧,我在这里可以互换地使用 numpy 和 torch 数据,我愿意使用所有 3 种方法来解决它
  • 好的,所以...接受一个索引元组作为输入,并用它来切片?像: 这样的切片索引由内置的slice 类型表示。

标签: python numpy pytorch


【解决方案1】:

在 Python 中,类型的索引操作由 __getitem__/__setitem__/__delitem__ magic methods 实现。要了解如何解释索引语法以及如何调用这些方法,我们可以简单地定义我们自己的类:

class test:
    def __getitem__(self, idx):
        return idx

test()[:, [1,2,3], ...]
# result: (slice(None, None, None), [1, 2, 3], Ellipsis)

slice 类型是前面在同一文档中提到的内置类型,带有指向more specific information 的链接。

Ellipsis 只是由文字语法... 创建的对象的名称。它是 Numpy 用来表示任意数量轴的完整范围的方法 - 所以这让我们不必担心我们正在使用的数组的维度。

要意识到的重要一点是,我们可以直接使用相同的索引元组来获得相同的结果。

因此,给定一个用[ci] 切片的维度,我们可以构造必要的元组,并用它进行索引:

all = slice(None)
def make_index(ci, dimension):
    return (all,) * dimension + ([ci], Ellipsis)

# Now we can do things like:
arr[make_index(ci, dimension)] = some_data

【讨论】:

  • 谢谢!表征用例;在排列期间迭代每一列时,我使用ci 表示列索引。如果用户对数据进行了重构,感兴趣的维度就会发生变化(不幸的是,不同的算法需要对维度进行重新排序)。
猜你喜欢
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 2016-04-06
  • 2014-06-06
  • 1970-01-01
  • 2018-12-17
相关资源
最近更新 更多