【问题标题】:More pythonic way to iterate through volume in arbitrary axis?在任意轴上迭代体积的更 Pythonic 方式?
【发布时间】:2019-09-25 19:35:03
【问题描述】:

我有一个函数,它接受一个 3D numpy 数组(我们将其称为卷),并将其转换为 2D 切片列表。我希望用户能够指定对其进行切片的轴。我用下面的代码来管理这个,但是三重 if 语句似乎不是最优雅的方法。我会很感激人们对是否可以以更好的方式实现这一点的想法。

axis = 0 # Can be set to 0, 1, or 2 

volume = np.ones((100, 100, 100))

n_slices = volume.shape[axis]

slices = []

for i in range(n_slices):

    if axis == 0:
        my_slice = volume[i, :, :]
    elif axis == 1:
        my_slice = volume[:, i, :]
    elif axis == 2:
        my_slice = volume[:, :, i]

    slices.append(my_slice)

【问题讨论】:

    标签: python arrays numpy volume nibabel


    【解决方案1】:

    只需使用np.moveaxis -

    slices_ar = np.moveaxis(volume,axis,0)
    

    最好的部分是它是输入视图,因此在运行时几乎是免费的。让我们验证view-part -

    In [83]: np.shares_memory(volume, np.moveaxis(volume,axis,0))
    Out[83]: True
    

    或者,使用 np.rollaxis 做同样的事情 -

    np.rollaxis(volume,axis,0)
    

    【讨论】:

    • 谢谢,没想到这个。被选为正确答案是因为它在我稍微复杂一点的场景中仍然有效,没有问题:有些卷有一个通道,有些则有更多
    【解决方案2】:

    你可以使用

    my_slice = volume[tuple(i if n == axis else slice(100) for n in range(3))]
    

    这样

    slices = [volume[tuple(i if n == axis else slice(100) for n in range(3))] for i in range(100)]
    

    【讨论】:

      【解决方案3】:

      我猜你想要的是 [numpy.split()]:(https://docs.scipy.org/doc/numpy/reference/generated/numpy.split.html)

      axis = 0 # Can be set to 0, 1, or 2 
      volume = np.ones((100, 100, 100))
      n_slices = volume.shape[axis]
      
      slices = np.split(volume, n_slices, axis)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-18
        • 2010-11-21
        • 2016-11-17
        • 2013-12-14
        • 2011-04-19
        • 2011-05-04
        • 2018-11-28
        相关资源
        最近更新 更多