I have been using this method for Ranges. I can't work out an equivalent method for fixed lists/arrays.
# 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)
Bad code:
# 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
With the benefit of hindsight I would have used lists... But now I wish to use this as learning opportunity.
Update: Answers as provided by @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)
My main mistake was the initialization of the array as wrong shape.
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)
CodePudding user response:
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.