<div dir="ltr"><div class="gmail_quote"><div dir="ltr">Hi everyone,</div><div dir="ltr"><br></div><div dir="ltr">Here's a problem I've been dealing with. I wonder whether NumPy has a tool that will help me, or whether this could be a useful feature request. <div><br></div><div>In the upcoming EuroPython 20200, I'll do a talk about <a>live-coding a music synthesizer</a>. It's going to be a fun talk, I'll use the <a href="https://github.com/spatialaudio/python-sounddevice/" target="_blank">sounddevice</a> module to make a program that plays music. Do attend, or watch it on YouTube when it's out :)</div><div><br></div><div>There's a part in my talk that I could make simpler, and thus shave 3-4 minutes of cumbersome explanations. These 3-4 minutes matter a great deal to me. But for that I need to do something with NumPy and I don't know whether it's possible or not. </div><div><br></div><div><div><br></div><div>The sounddevice library takes an ndarray of sound data and plays it. Currently I use `vectorize` to produce that array:</div></div><div><br></div><div>    <span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">output_array </span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">=</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit"> np</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">.</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">vectorize</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">(</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">f</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">,</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit"> otypes</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">=</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">'d'</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">)(</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">input_array</span><span style="background-color:transparent;font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;white-space:inherit;color:rgb(36,39,41);font-size:13px;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">)</span></div><br><div>And I'd like to replace it with this code, which is supposed to give the same output:<br><br>    output_array = np.ndarray(input_array.shape, dtype='d')<br>    for i, item in enumerate(input_array):<br>        output_array[i] = f(item)<br></div><div><br></div><div>The reason I want the second version is that I can then have sounddevice start playing `output_array` in a separate thread, while it's being calculated. (Yes, I know about the GIL, I believe that sounddevice releases it.)</div><div><br></div><div>Unfortunately, the for loop is very slow, even when I'm not processing the data on separate thread. I benchmarked it on both CPython and PyPy3, which is my target platform. On CPython it's 3 times slower than vectorize, and on PyPy3 it's 67 times slower than vectorize! That's despite the fact that the Numpy documentation says "The `vectorize` function is provided primarily for convenience, not for performance. The implementation is essentially a `for` loop."<br><br></div><div>So here are a few questions:</div><div><br></div><div>1. Is there something like `vectorize`, except you get to access the output array before it's finished? If not, what do you think about adding that as an option to `vectorize`?</div><div><br></div><div>2. Is there a more efficient way of writing the `for` loop I've written above? Or any other kind of solution to my problem?</div><div><br></div><div><br></div><div>Thanks for your help,</div><div>Ram Rachum.</div></div>
</div></div>