Python Numpy数组既不是C也不是F TL;问题博士

Python Numpy数组既不是C也不是F TL;问题博士,python,arrays,numpy,memory,python-internals,Python,Arrays,Numpy,Memory,Python Internals,关于相邻C或F连续的numpy数组(数组的C_连续和F_连续标志为False): 数组真的不能是C或F连续的吗?还是说假标志只是意味着numpy不能找出正确的连续类型 这类阵列的性能影响是什么?在这种状态下,我们是否错过了任何优化 数组,例如: import numpy as np arr = np.random.randint(0, 255, (1000, 1000, 3), dtype='uint8') arr = arr[:, :, ::-1] assert arr.flags.c_con

关于相邻C或F连续的numpy数组(数组的C_连续和F_连续标志为False):

  • 数组真的不能是C或F连续的吗?还是说假标志只是意味着numpy不能找出正确的连续类型
  • 这类阵列的性能影响是什么?在这种状态下,我们是否错过了任何优化
  • 数组,例如:

    import numpy as np
    arr = np.random.randint(0, 255, (1000, 1000, 3), dtype='uint8')
    arr = arr[:, :, ::-1]
    assert arr.flags.c_contiguous is False
    assert arr.flags.f_contiguous is False
    
    背景 我正在尝试优化一个简单的代码块,该代码块在程序中被多次调用。
    此代码块负责加载PIL图像,将其转换为numpy数组,反转其通道并返回它。
    大概是这样的:

    import numpy as np
    from PIL import Image
    
    def load_image(path):
        arr = np.asarray(Image.open(path).convert('RGB'))
        return arr[:, :, ::-1].copy()
    
    最初的
    copy()
    调用是为了将返回值强制为C顺序数组,但是,我想知道是否有一种方法可以在不每次复制数组的情况下实现相同的效果,因为这听起来非常昂贵。
    我尝试将
    copy()
    调用替换为
    np.ascontiguousarray()
    ,但基准测试显示它们是相同的,因此我猜它也会在幕后执行复制

    我最终决定应用这个解决方案:

    import numpy as np
    from PIL import Image
    
    def load_image(path):
        arr = np.ascontiguousarray(Image.open(path).convert('RGB'))
        return arr[:, :, ::-1]
    
    在这里,我将图像转换为C-有序数组,这可能会在幕后产生副本,但事实上不会,因为在基准测试中,此函数比前一个快X3-X4。

    但是,我想确保我不会通过返回一个不是C或F顺序的数组来取消任何未来的优化。

    如果您只执行一个操作,例如反转通道,并且必须对数据进行切片,那么我猜任何获取连续数据的努力都是无用的-无法避免复制所有数据,这将涉及所有相同的缓存未命中,因为只需按原样处理数据就可以了。为什么不试试
    OpenCV
    ?它读取图像的速度比
    PIL
    快,并将BGR图像作为numpy数组提供给您。在我使用的代码库中,调用从OpenCV切换到PIL,因为它在读取图像时不会提供错误反馈。对此有一个明确的评论。虽然这是一个很好的方向,但我将尝试找出遗漏了哪些错误,并看看是否可以再次使用OpenCV。但是它在几个月前就被切换了。
    视图
    副本
    之间的区别很重要,但是某些东西是F、C还是两者都不连续通常是不连续的,除非是一些下游操作对象。如果你只做一个操作,比如反转通道,并且还必须对数据进行切片,那么我想,任何获取连续数据的努力都是无用的——没有办法避免复制所有数据,这将涉及所有相同的缓存未命中,因为只按原样处理数据就可以了。为什么不试试
    OpenCV
    ?它读取图像的速度比
    PIL
    快,并将BGR图像作为numpy数组提供给您。在我使用的代码库中,调用从OpenCV切换到PIL,因为它在读取图像时不会提供错误反馈。对此有一个明确的评论。虽然这是一个很好的方向,但我将尝试找出遗漏了哪些错误,并看看是否可以再次使用OpenCV。但是它在几个月前就被切换了。
    视图
    副本
    之间的区别很重要,但某些对象是F、C还是两者都不连续通常并不重要,除非某些下游操作对象。