1
\$\begingroup\$

I'm seeing a web course of computational statistics, the first project consists of a random walker, the implementation I have done works as intended:

import numpy as np
import numpy.random as rd
import matplotlib.pyplot as plt

WALKER_STEPS: int = 5_000

# random orientation converted from degrees to radians
directions: np.array = rd.uniform(low=0, high=360, size=WALKER_STEPS) * np.pi / 180

x: list = [0]
y: list = [0]
idx: int = 0
for rad in directions:
    # updates the positions of the walker
    x.append(x[idx] + np.cos(rad))
    y.append(y[idx] + np.sin(rad))
    idx += 1

plt.plot(x, y)
plt.show()

I don't like the way I'm adding new elements to the lists x, y and I think that there's a more elegant way to do it.

Here a image of the result:

Execution of Random Walk Algorithm

Note: I didn't do an abstraction because the exercise in small.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Why do you feel that you need to improve performance here? I tested the code, and running 5000 iterations only takes around 20ms which feels pretty fast. Is it just for personal interest, or is there some requirement? \$\endgroup\$
    – maxb
    Feb 15, 2021 at 8:02
  • \$\begingroup\$ @maxb It's personal interest, I'm near to get my degree (I hope) and I feel quite nervious regarding the "real world" (my work after getting a job). I feel like I haven't learned well in college so I'm doing web courses. \$\endgroup\$ Feb 15, 2021 at 17:31
  • 1
    \$\begingroup\$ I get that feeling. While this might wander a bit off topic, I'll say that studying to become a programmer/software engineer and actually working as one are two very different things. However, you'll learn a ton of stuff at your first job, so your days of learning definitely don't end when you get your degree. Best of luck! \$\endgroup\$
    – maxb
    Feb 16, 2021 at 11:49

1 Answer 1

2
\$\begingroup\$

Use np.cumsum()

import numpy as np
import numpy.random as rd
import matplotlib.pyplot as plt
WALKER_STEPS: int = 5_000

# random orientation converted from degrees to radians
directions: np.array = rd.uniform(low=0, high=360, size=WALKER_STEPS) * np.pi / 180

x = np.cos(directions).cumsum()
y = np.sin(directions).cumsum()

plt.plot(x, y)
plt.show()
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is a really great improvement, but not strictly equal to the original code since it doesn't add the 0 value at the start of the array. You could just do something like x = np.empty(WALKER_STEPS+1); y = np.empty(WALKER_STEPS+1); x[0] = 0; y[0] = 0; x[1:] = np.cos(directions).cumsum(); y[1:] = np.sin(directions).cumsum() (sorry for the clutter) which exactly reproduces the original code but keeps the performance of your solution. \$\endgroup\$
    – maxb
    Feb 15, 2021 at 8:08

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.