1

Here is mentioned that appending to numpy array is not an good idea because it requires re-allocation of the array memory and it slows down the code. There are also mentioned some hints how to avoid it. My goal is to create an saw signal, something like this ASCII art: /\/\/\/\. I've end up with following two codes and I do not know which one is worse. 2nd one uses also itertools.islice which is also not world's speed recorder as it discussed here. Both codes mixes standard python lists and numpy arrays. Is there a way how can achieve the same but using pure numpy arrays? Or better: is there any general rule which I can use with numpy everywhere where I would use list.append instead? As I said on 1st page are mentioned some hints but I cannot figure out working solution. I've been thinking about something like list comprehension that will allow me expand the saw array first which then I could pass to np.hstack but I do not think this is possible. I've been also thinking about first declaring numpy array with numpy.empty(400) or np.zeros(400) but I do not know how to properly assign to them further values and seems that np.empty is not so completely empty because it contains zero values:

In [106]: x = np.zeros(10)
In [107]: x
Out[107]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

In [108]: y = np.empty(10)
In [109]: y
Out[109]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

1st

import numpy as np
import matplotlib.pyplot as plt

saw = []
for x in xrange(0, 3):
  saw.append(np.hstack((np.linspace(0,1,50), np.linspace(1,0,50))))
saw2 = saw[0]
for x in saw:
  saw2 = np.append([saw2], [x])
plt.figure()
plt.plot(np.arange(saw2.size), saw2)
plt.show()

2nd

import numpy as np
from itertools import islice
import matplotlib.pyplot as plt

saw = []
for x in xrange(0, 4):
  saw.append(np.hstack((np.linspace(0,1,50), np.linspace(1,0,50))))
saw2 = saw[0]
for x in islice(saw, 1, None, 1):
  saw2 = np.append([saw2], [x])
plt.figure()
plt.plot(np.arange(saw2.size), saw2)
plt.show()
3
  • 1
    You might try doing some performance testing to find out what is really most efficient. Some things worth testing are insert at the beginning vs at the end vs append vs contatenate. Some results are at stackoverflow.com/questions/7133885/…. Commented Jul 30, 2015 at 13:09
  • 2
    Generally - work out the size of your array first. Then allocate an array of this size with, say, np.zeros or np.empty. Then assign the results to the appropriate slice of the array, e.g. saw[start_index:end_index] = ... Commented Jul 30, 2015 at 13:21
  • Thanks for tips guys Commented Jul 31, 2015 at 20:56

1 Answer 1

1

Your 2 iterations are only of size 3. That's to construct an array that is (400,). That kind of iteration isn't something to worry about much.

I can clean up your code by writing it as:

xup=np.linspace(0,1,50)
xdn=np.linspace(1,0,50)
x=np.hstack([xup,xdn])
saw2 = np.hstack([x for _ in range(4)])

The list comprehension is just your saw.

np.stack (or np.concatenate) takes a list (or lists or arrays), so there's no need to iterate through the list, doing a concatenate item by item. np.append is just a pairwise concatenate:

 np.append(saw2,x) == np.concatenate([saw2,x])

It's even simpler to use np.tile to replicate x

saw2 = np.tile(x,4)

or something a bit faster (tile uses repeat in a similar way)

saw2 = x[None,:].repeat(4,0).flatten()
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for valuable hints

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.