为什么循环中追加的数组长度比迭代次数多?

问题描述 投票:1回答:2

我运行了这段代码,预期数组大小为10000,为 time 是一个长度为10000的numpy数组。

freq=np.empty([])
for i,t in enumerate(time):
    freq=np.append(freq,np.sin(t))
print(time.shape)
print(freq.shape)

但这是我得到的输出

(10000,)
(10001,)

谁能解释一下为什么我得到了这种差异?

python numpy for-loop append
2个回答
0
投票

原来,函数 np.empty() 返回一个给定形状的未初始化数组。因此,当你执行 np.empty([])它返回一个未初始化的数组,如 array(0.14112001). 这就像拥有一个 "准备使用 "的值,但没有实际的值。你可以通过打印变量 freq 循环开始前。

所以,当你循环到 freq = np.append(freq,np.sin(t)) 这实际上是初始化数组并添加第二个值。

另外,如果你只需要创建一个空数组,只需执行 x = np.array([])x = [].

你可以在这里阅读更多关于这个numpy.empty函数的信息。

https:/numpy.orgdoc1.18referencegeneratednumpy.empty.html。

而更多关于初始化数组的内容在这里。

https:/www.ibm.comsupportknowledgecenterSSGH2K_13.1.3com.ibm.xlc1313.aix.doclanguage_refaryin.html

我不知道我是否足够清楚。这不是一个简单的概念。所以请告诉我。


0
投票

你应该填写np.empty(0)。

我找numpy的源代码 numpycore.py

def empty(shape, dtype=None, order='C'):
"""Return a new matrix of given shape and type, without initializing entries.
Parameters
----------
shape : int or tuple of int
    Shape of the empty matrix.
dtype : data-type, optional
    Desired output data-type.
order : {'C', 'F'}, optional
    Whether to store multi-dimensional data in row-major
    (C-style) or column-major (Fortran-style) order in
    memory.
See Also
--------
empty_like, zeros
Notes
-----
`empty`, unlike `zeros`, does not set the matrix values to zero,
and may therefore be marginally faster.  On the other hand, it requires
the user to manually set all the values in the array, and should be
used with caution.
Examples
--------
>>> import numpy.matlib
>>> np.matlib.empty((2, 2))    # filled with random data
matrix([[  6.76425276e-320,   9.79033856e-307], # random
        [  7.39337286e-309,   3.22135945e-309]])
>>> np.matlib.empty((2, 2), dtype=int)
matrix([[ 6600475,        0], # random
        [ 6586976, 22740995]])
"""
return ndarray.__new__(matrix, shape, dtype, order=order)

它会将第一个arg形状输入ndarray,所以它会初始化一个新的数组为[]。

然后你可以打印 np.empty(0)freq=np.empty([]) 来看看它们有什么不同。


0
投票

我想你是想复制一个列表操作。

freq=[]
for i,t in enumerate(time):
     freq.append(np.sin(t))

但无论是 np.emptynp.append 是完全的克隆,名称相近,但差别很大。

首先,这是一个1元素,0d的数组。

In [75]: np.empty([])                                                                                  
Out[75]: array(1.)
In [77]: np.empty([]).shape                                                                            
Out[77]: ()

这是一个1个元素,0d的数组。

如果你看一下 np.append 你会发现,如果第1个参数不是1d(没有提供轴),它就会 flattens 它(这也是有记录的)。

In [78]: np.append??                                                                                   
In [82]: np.empty([]).ravel()                                                                          
Out[82]: array([1.])
In [83]: np.empty([]).ravel().shape                                                                    
Out[83]: (1,)

它不是一个1d, 1元素的数组. 用另一个数组来追加。

In [84]: np.append(np.empty([]), np.sin(2))                                                            
Out[84]: array([1.        , 0.90929743])

结果是2d. 重复1000次,你最终得到1001个值。

np.empty 尽管它的名字很好听,但它不会产生一个 [] 列表等同。 正如其他人所显示的 np.array([]) 算是吧 np.empty(0).

np.append 不是一个列表追加克隆。 它只是一个覆盖函数,用于 np.concatenate. 对于向一个较长的数组添加元素来说,它是可以的,但除此之外,它有太多的陷阱,无法发挥作用。特别是在这样的循环中,它的作用就更大了。 获得一个正确的起始数组是很棘手的。 而且它的速度很慢(与list append相比)。 事实上,这些问题适用于所有使用 concatenatestack... 循环中。

© www.soinside.com 2019 - 2024. All rights reserved.