代码之家  ›  专栏  ›  技术社区  ›  Sterling Butters

Numpy:沿移动轴执行原位操作

  •  1
  • Sterling Butters  · 技术社区  · 2 年前

    好的,我尽力在标题中描述了我的问题。

    我的问题如下:

    我有一个numpy数组,它可能并不总是具有一致的形状/维度(范围从1到3)。以阵列形状为[100]的最简单情况为例,我可以执行以下操作(并获得所需结果):

    for i, bounds in enumerate(values):
        low, high = bounds
        arr[i] *= high - low
    

    当数组的形状为[10002]时,我可以执行以下操作:

    for i, bounds in enumerate(values):
        low, high = bounds
        arr[i, :] *= high - low
    

    或者如果数组的形状是[200100],我可以改为:

    for i, bounds in enumerate(values):
        low, high = bounds
        arr[:, i] *= high - low
    

    在3d的情况下,如果阵列的形状是[300100020],我会这样做:

    for i, bounds in enumerate(values):
        low, high = bounds
        arr[:, i, :] *= high - low
    

    我的问题是我不知道如何改变的位置 i 在索引中,或者在对应于的轴上迭代时如何索引所有元素 (当的形状 arr 正在发生变化)。在我的示例中,的“位置” 基于何处 100 落在阵列的形状中。这是numpy可以做的事情吗?还是我被一些if语句卡住了?

    1 回复  |  直到 2 年前
        1
  •  2
  •   Intrastellar Explorer    2 年前

    一种可能性是移动轴,将您想要的轴(根据您的标准)放在新视图中的第一位 a2 然后 a2[i,:,:] 与相同 arr[:,i,:] (例如)如果正确的轴是1。另外,这样,您可以使用 ... 符号,以替换所有 : 所以 a2[i,...] .

    # Move axis whose size is 100 in 1st position (index 0) in a2 view
    # (a2 is a view of arr. So modifying its contents change arr content).
    # Note, if the 1st axis is already of size 100 this will do nothing
    a2 = np.moveaxis(arr, arr.shape.index(100), 0) 
    
    for i, (low, high) in enumerate(values):
        a2[i, ...] *= high - low
        # Note this `...` works whatever the dimension, even 1.
    
        2
  •  1
  •   Barmar    2 年前

    您可以动态创建索引。索引集是一个元组,并且 : slice(None) .

    在维度中查找与值长度相同的索引。然后更新循环中索引列表列表中的索引。

    indexes = [slice(None)] * arr.ndims
    variable_pos = arr.shape.index(len(values))
    for i, (low, high) in enumerate(values):
        indexes[variable_pos] = i
        arr[tuple(indexes)] *= high - low