numpy 追加到数组或从固定数组循环迭代

mo49yndu  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(162)

我一直在用这个方法来处理范围。我不能为固定的列表/数组找到一个等价的方法。

# What I've been using & OUTPUT I'm looking for.

degrees = np.arange(10,50,10)
ITER = np.array(degrees)
for i in range( 4): 
    x1 = np.sin(np.radians(ITER))
    y1 = np.cos(np.radians(ITER ))
XY = np.column_stack((np.asarray(x1),np.asarray(y1)))
print(XY)

错误代码:

# appending to array has seen many failures.  
# appended array always prints empty. must have a false assumption
xy1 = np.array([])
degrees = np.array([10, 20, 30, 40])
for degree in np.nditer(degrees):
    x1 = np.sin(np.radians(degree))
    y1 = np.cos(np.radians(degree))
    #np.append(xy1,[x1,y1]).reshape(2,1)
    #ugh = np.asarray([x1,y1])
    #a = np.append(xy1,[[x1,y1]],axis =0).reshape(2,-1)
    #a = np.append(xy1,[[x1],[y1]],axis =0)#.reshape(2,-1)
    #np.append(xy1,ugh, axis =0).reshape(2,1)
    #np.append(xy1,ugh, axis =0)
    #a = np.append(xy1,[ugh])
XY = np.column_stack((np.asarray(x1),np.asarray(y1)))
print(xy1)

# OUTPUT should be same as working example above

事后看来,我本来会用清单的...但现在我希望把这个作为学习的机会。

***更新:***答案由@hpaulj提供

# Iterate through Range
degrees = np.arange(10,50,10)
x1 = np.sin(np.radians(degrees))
y1 = np.cos(np.radians(degrees ))
XY = np.column_stack((x1, y1))

# Iterate through fixed list
degrees = np.array([10, 20, 30, 40])
XY = np.zeros((0,2))
for rad in np.radians(degrees):
    XY = np.append(XY, [[np.sin(rad), np.cos(rad)]], axis=0)

我的主要错误是数组初始化为错误的形状。

XY = np.zeros((0,2))
degrees = np.array([10, 20, 30, 40])
for rads in np.radians(degrees):
    x1 = np.sin(rads)
    y1 = np.cos(rads)
    XY = np.append(XY, [[x1,y1]]).reshape(-1,2)
fnx2tebb

fnx2tebb1#

Your first code runs; why are you trying to write something else?
But I think you need to understand the first one better. Let's run it:

In [449]: degrees = np.arange(10,50,10)
     ...: ITER = np.array(degrees)
     ...: for i in range( 4): 
     ...:     x1 = np.sin(np.radians(ITER))
     ...:     y1 = np.cos(np.radians(ITER ))
     ...: XY = np.column_stack((np.asarray(x1),np.asarray(y1)))

In [450]: degrees
Out[450]: array([10, 20, 30, 40])

In [451]: ITER
Out[451]: array([10, 20, 30, 40])

arange produces an array (READ THE DOCS); so why the extra np.array(degrees) call? It doesn't change any; it just makes a another copy.

In [452]: XY
Out[452]: 
array([[0.17364818, 0.98480775],
       [0.34202014, 0.93969262],
       [0.5       , 0.8660254 ],
       [0.64278761, 0.76604444]])

degrees is (4,) shape; x1 is as well, and XY is (4,2), concatenating two 1d arrays as columns.
Why the iteration for range(4) ? Just to make the code run slower by repeating the sin calculations? You do the same thing 4 times, and don't accumulate anything. It just uses the last run to make XY . And x1 is already an array; why the extra np.array(x1) wrapping?

In [453]: x1,y1
Out[453]: 
(array([0.17364818, 0.34202014, 0.5       , 0.64278761]),
 array([0.98480775, 0.93969262, 0.8660254 , 0.76604444]))

In [454]: np.sin(np.radians(ITER))
Out[454]: array([0.17364818, 0.34202014, 0.5       , 0.64278761])

I don't know whether you are just being careless, or don't understand the basics of Python iteration.
This is all you need:

degrees = np.arange(10,50,10)
x1 = np.sin(np.radians(ITER))
y1 = np.cos(np.radians(ITER ))
XY = np.column_stack((x1, y1))

2nd try

I just noticed you use np.nditer . Why? If you are going to iterate, use the straight forward

for degree in degress:
       ....

nditer is not a faster way of iterating; the docs may be misleading in this regard. It is really only useful as a stepping stone toward writing fancy iterations in cython . The python version is slow - and overly complicated for most users.
As the first code shows, you don't need to iterate to calculate sin/cos for all degrees . But if you must iterate, here's a simple clear version:

In [457]: degrees = np.arange(10,50,10)
     ...: x1, y1 = [], []
     ...: for degree in degrees:
     ...:     x1.append(np.sin(np.radians(degree)))
     ...:     y1.append(np.cos(np.radians(degree)))
     ...: XY = np.column_stack((np.array(x1), np.array(y1)))

In [458]: x1
Out[458]: 
[0.17364817766693033,
 0.3420201433256687,
 0.49999999999999994,
 0.6427876096865393]

x1 , y1 are lists; list append is relatively fast, and simple. np.append is slow and hard to use correctly. Don't use it (like nditer it needs a stronger disclaimer, and maybe even removal).
Here's a version of iteration with np.append that works; I don't recommend it, but it illustrates how np.append might work:

In [461]: degrees = np.arange(10,50,10)
 ...: XY = np.zeros((0,2))
 ...: for rad in np.radians(degrees):
 ...:     XY = np.append(XY, [[np.sin(rad), np.cos(rad)]], axis=0)

I do just one np.radians conversion. No need to repeat or do it in the iteration.
I initial XY as a (0,2) array - and I add a (1,2) array to it at each iteration. np.append with axis is just

XY = np.concatenate((XY, [[np.sin...]]), axis=0)

Your failed tries have various problems. np.array([]) has shape (0,). You can't join a (2,) to that with axis ). np.append returns a new array; it does not work in-place. None of your tries changes xy1 .
Looking more at that second block of code, I get the impression that you are just being careless. You mix xy1 , x1 , y1 , a , XY without paying attention to how they might, or might not, be related.

相关问题