0

I want to build an array of points where each row depends on the corresponding row of a timestep array as in:

steps = 5
output = np.empty((steps, 3))
timesteps = np.linspace(0, 1, steps)

for i, step in enumerate(timesteps):
    output[i] = [sin(step), cos(step), 0]

With the expected output:

[[0.         1.         0.        ]
 [0.24740396 0.96891242 0.        ]
 [0.47942554 0.87758256 0.        ]
 [0.68163876 0.73168887 0.        ]
 [0.84147098 0.54030231 0.        ]]

How can I vectorize this operation?


I could assign each column independently like so:

out[:, 0] = np.sin(timesteps)
out[:, 1] = np.cos(timesteps)
out[:, 2] = 0

But I'd like to maintain a row-based approach for readability, if possible.

I was thinking of something like

output[:] = [np.sin(timesteps[:]), np.cos(timestep[:]), 0]

but obviously that doesn't work due to setting an array element with a sequence.

2
  • 2
    The column assignment is the right way to do this. I don't see how that makes things any less readable. Commented Jun 8, 2021 at 18:09
  • @TimRoberts I suppose it hides the point=row relation a bit, but yeah, not a big issue. Commented Jun 8, 2021 at 18:18

2 Answers 2

3

you can create a numpy array in the following way:
np.array([np.sin(timesteps), np.cos(timesteps), [0]*len(timesteps)])

However this sets sines as the first line, cosines as second and so on. To change them from being lines to being columns you can use the transpose() method also accesible via the .T attribute. Finally you'd get:

output = np.array([np.sin(timesteps), 
                   np.cos(timesteps), 
                   [0]*len(timesteps)]).transpose()

or
output = np.array([np.sin(timesteps), np.cos(timesteps), [0]*len(timesteps)]).T

I find this close enough to what you tried and guess this is ok about the "readability" concern. To check that this is indeed what you want:

import numpy as np

steps = 5
output = np.empty((steps, 3))
timesteps = np.linspace(0, 1, steps)

for i, step in enumerate(timesteps):
    output[i] = [np.sin(step), np.cos(step), 0]

output -= np.array([np.sin(timesteps), np.cos(timesteps), [0]*len(timesteps)]).transpose()

print(output)

> [[0. 0. 0.]
  [0. 0. 0.]
  [0. 0. 0.]
  [0. 0. 0.]
  [0. 0. 0.]]

NB: [0]*len(timesteps) create a list of size len(timesteps) populated only with zeros

Sign up to request clarification or add additional context in comments.

Comments

1

I have something looks like this, can you try that ?

output[:] = [np.sin(timesteps[:]), np.cos(timestep[:]), 0]

Here is my solution:

import numpy as np
steps = 5
timesteps = np.linspace(0, 1, steps)

out=np.concatenate(([np.sin(timesteps)],[np.cos(timesteps)],[np.zeros(steps)]))

out=out.transpose()

out
array([[0.        , 1.        , 0.        ],
       [0.24740396, 0.96891242, 0.        ],
       [0.47942554, 0.87758256, 0.        ],
       [0.68163876, 0.73168887, 0.        ],
       [0.84147098, 0.54030231, 0.        ]])

I think this would be helpful, let me know any issue persists.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.