映射一个NumPy数组

发布于 2021-01-29 18:59:30

是否可以将NumPy数组映射到位? 如果是,怎么办?

给定a_values-2D数组-这是目前为我完成窍门的一些代码:

for row in range(len(a_values)):
    for col in range(len(a_values[0])):
        a_values[row][col] = dim(a_values[row][col])

但是它是如此丑陋,以至于我怀疑在NumPy内的某个地方一定有一个函数可以对以下内容执行相同的操作:

a_values.map_in_place(dim)

但是如果存在上述类似内容,我将无法找到它。

关注者
0
被浏览
47
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    只有在空间有限的情况下,才值得尝试就地执行此操作。如果是这样,可以通过遍历数组的展平视图来稍微加快代码的速度。由于在可能的情况下会reshape返回新视图,因此不会复制数据本身(除非原始数据具有异常的结构)。

    我不知道一种更好的方法来实现任意Python函数的真正就地应用。

    >>> def flat_for(a, f):
    ...     a = a.reshape(-1)
    ...     for i, v in enumerate(a):
    ...         a[i] = f(v)
    ... 
    >>> a = numpy.arange(25).reshape(5, 5)
    >>> flat_for(a, lambda x: x + 5)
    >>> a
    
    array([[ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14],
           [15, 16, 17, 18, 19],
           [20, 21, 22, 23, 24],
           [25, 26, 27, 28, 29]])
    

    一些时间:

    >>> a = numpy.arange(2500).reshape(50, 50)
    >>> f = lambda x: x + 5
    >>> %timeit flat_for(a, f)
    1000 loops, best of 3: 1.86 ms per loop
    

    它大约是嵌套循环版本的两倍:

    >>> a = numpy.arange(2500).reshape(50, 50)
    >>> def nested_for(a, f):
    ...     for i in range(len(a)):
    ...         for j in range(len(a[0])):
    ...             a[i][j] = f(a[i][j])
    ... 
    >>> %timeit nested_for(a, f)
    100 loops, best of 3: 3.79 ms per loop
    

    当然矢量化仍然更快,因此,如果可以进行复制,请使用以下方法:

    >>> a = numpy.arange(2500).reshape(50, 50)
    >>> g = numpy.vectorize(lambda x: x + 5)
    >>> %timeit g(a)
    1000 loops, best of 3: 584 us per loop
    

    如果可以dim使用内置的ufuncs进行重写,请不要vectorize

    >>> a = numpy.arange(2500).reshape(50, 50)
    >>> %timeit a + 5
    100000 loops, best of 3: 4.66 us per loop
    

    numpy就像+=您所期望的那样执行类似的操作-
    因此您可以免费使用就地应用程序来获得ufunc的速度。有时甚至更快!请参阅此处的示例。


    顺便说一句,我对这个问题的原始答案很荒谬,涉及到将索引向量化到,这个答案在编辑历史记录中可以看到a。它不仅必须做一些时髦的东西,以旁路vectorize类型检测机制,它竟然是一样缓慢,因为嵌套循环版本。太聪明了!



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看