代码之家  ›  专栏  ›  技术社区  ›  wim

从np.empty初始化numpy数组

  •  6
  • wim  · 技术社区  · 7 年前

    从空内存初始化NDAREL时,符号位是如何确定的?

    >>> np.random.randn(3,3)
    array([[-0.35557367, -0.0561576 , -1.84722985],
           [ 0.89342124, -0.50871646,  1.31368413],
           [ 0.0062188 ,  1.62968789,  0.72367089]])
    >>> np.empty((3,3))
    array([[0.35557367, 0.0561576 , 1.84722985],
           [0.89342124, 0.50871646, 1.31368413],
           [0.0062188 , 1.62968789, 0.72367089]])
    

    从空内存初始化的这些浮点值已经失去它们的符号。 - 是的。为什么?

    - 注意:这个结果依赖于内存重用的实现细节。这个问题问的是实现在做什么。

    2 回复  |  直到 7 年前
        1
  •  4
  •   user2357112    7 年前

    numpy.empty 不是手动或任何东西清除符号位。符号位就是那些 malloc 返回值。你看到的效果是由于 numpy.absolute 打别的电话。

    问题是, 空的 不是在重复使用 randn 返回值的缓冲区。毕竟, 兰登 返回值在以下情况下仍然有效 empty 创建其数组,因为 _ 变量。

    空的 正在重用在 架线 第一个数组。我想是 this one 以下内容:

    def fillFormat(self, data):
        # only the finite values are used to compute the number of digits
        finite_vals = data[isfinite(data)]
    
        # choose exponential mode based on the non-zero finite values:
        abs_non_zero = absolute(finite_vals[finite_vals != 0])
        ...
    

    看那个 absolute 打电话?就是那个。

    以下是支持这一结论的一些附加测试:

    >>> a = numpy.random.randn(3, 3)
    >>> b = numpy.arange(-5, 4, dtype=float)
    >>> c = numpy.arange(-5, 13, 2, dtype=float)
    >>> a
    array([[-0.96810932,  0.86091026, -0.32675013],
           [-1.23458136,  0.56151178, -0.37409982],
           [-1.71348979,  0.64170792, -0.20679512]])
    >>> numpy.empty((3, 3))
    array([[ 0.96810932,  0.86091026,  0.32675013],
           [ 1.23458136,  0.56151178,  0.37409982],
           [ 1.71348979,  0.64170792,  0.20679512]])
    >>> b
    array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.])
    >>> numpy.empty((3, 3))
    array([[ 0.96810932,  0.86091026,  0.32675013],
           [ 1.23458136,  0.56151178,  0.37409982],
           [ 1.71348979,  0.64170792,  0.20679512]])
    >>> c
    array([ -5.,  -3.,  -1.,   1.,   3.,   5.,   7.,   9.,  11.])
    >>> numpy.empty((3, 3))
    array([[  5.,   3.,   1.],
           [  1.,   3.,   5.],
           [  7.,   9.,  11.]])
    >>> numpy.array([1.0, 0, 2, 3, 4, 5, 6, 7, 8, 9])
    array([ 1.,  0.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])
    >>> numpy.empty((3, 3))
    array([[ 1.,  2.,  3.],
           [ 4.,  5.,  6.],
           [ 7.,  8.,  9.]])
    

    这个 空的 结果受打印影响 a c ,而不是通过创建这些数组的过程。 b 没有效果,因为它有8个非零元素。决赛 array([1.0, 0, 2, ...]) 有效果,因为即使它有10个元素,其中9个元素都不是零。

        2
  •  0
  •   cgnorthcutt zwol    7 年前

    考虑到numpy是用c(和一些fortran,c++)编写的,而且答案可能与python无关,我将尝试使用几个例子来说明发生了什么。多语言方面使得这一点相当棘手,因此您可能需要检查np.empty()函数的实现: https://github.com/numpy/numpy/blob/master/numpy/matlib.py#L13

    你试过了吗:

    import numpy as np
    
    print(np.random.randn(3,3))
    print(np.empty((3,3)))
    

    我得到输出:(符号被保留)

    [[-1.13898052  0.99079467 -0.07773854]
     [ 1.18519122  1.30324795 -0.38748375]
     [-1.46435162  0.53163777  0.22004651]]
    [[-1.13898052  0.99079467 -0.07773854]
     [ 1.18519122  1.30324795 -0.38748375]
     [-1.46435162  0.53163777  0.22004651]]
    

    你会注意到行为的改变基于两件事:

    1. 无论是打印还是输出值
    2. 您创建了多少空数组

    例如,尝试运行以下两个示例:

    # Run this over and over and you'll always get different results!
    
    a = np.random.randn(3,3)
    b = np.empty((3,3))
    c = np.empty((3,3))
    print(a, id(a)) # id gives memory address of array
    print(b, id(b))
    print(c, id(c))
    

    输出:

    [[ 0.25754195  1.13184341 -0.46048928]
     [-0.80635852  0.92340661  2.08962923]
     [ 0.09552521  0.14940356  0.5644782 ]] 139865678073408
    [[-1.63665076 -0.41916461  0.9251386 ]
     [ 2.72595838  0.10575355 -0.03555088]
     [ 0.71242678  0.09749262  0.24742165]] 139865678071568
    [[-0.41824453  0.66565604  1.52995102]
     [ 0.8365397   0.32796832 -0.07150151]
     [-0.08558753  0.96326938 -0.56601338]] 139865678072688
    

    # Run this 2 or more times and b and c will always be the same!
    
    a = np.random.randn(3,3)
    b = np.empty((3,3))
    c = np.empty((3,3))
    >>> a, id(a) # output without using print
    
    (array([[-0.04230878,  0.18081425,  0.36880091],
        [ 0.4426956 , -1.31697583,  1.53143212],
        [ 0.58197615,  0.42028897,  0.27644022]]), 139865678070528)
    
    >>> b, id(b)
    
    (array([[-0.41824453,  0.66565604,  1.52995102],
        [ 0.8365397 ,  0.32796832, -0.07150151],
        [-0.08558753,  0.96326938, -0.56601338]]), 139865678048912)
    
    >>> c, id(c) # c will have the same values as b!
    
    (array([[-0.41824453,  0.66565604,  1.52995102],
        [ 0.8365397 ,  0.32796832, -0.07150151],
        [-0.08558753,  0.96326938, -0.56601338]]), 139865678069888)
    

    尝试连续运行每一次,以使内存有机会落入一个模式。另外,根据运行这两个块的顺序,您将得到不同的行为。

    注意到“空”数组B和C在打印和不打印时的行为,我猜想有一种“懒惰的评估”发生在使用输出时,因为内存仍然是“自由”的(这就是为什么C在最后一个例子中得到与B相同的值), python没有义务为没有实际分配内存的数组打印精确的值 (Malc),即无符号表示,或者任何东西都是公平的游戏,直到你使用。在我的例子中,我通过打印数组来“使用”数组,这可能解释了为什么在我的第一个例子中,你看到的符号是通过打印保存的。