2

Im working with two arrays, trying to work with them like a 2 dimensional array. I'm using a lot of vectorized calculations with NumPy. Any idea how I would populate an array like this:

X = [1, 2, 3, 1, 2, 3, 1, 2, 3]

or:

X = [0.2, 0.4, 0.6, 0.8, 0.2, 0.4, 0.6, 0.8, 0.2, 0.4, 0.6, 0.8, 0.2, 0.4, 0.6, 0.8]

Ignore the first part of the message.

I had to populate two arrays in a form of a grid. But the grid dimensions varied from the users, thats why I needed a general form. I worked on it all this morning and finally got what I wanted.

I apologize if I caused any confusion earlier. English is not my tongue language, and sometimes it is hard for me to explain things.

This is the code that did the job for me:

 myIter = linspace(1, N, N)
 for x in myIter:
 for y in myIter:
 index = ((x - 1)*N + y) - 1
 X[index] = x / (N+1)
 Y[index] = y / (N+1)

The user inputs N. And the length of X, Y is N*N.

BenMorel
36.9k52 gold badges208 silver badges339 bronze badges
asked Jul 13, 2011 at 15:20
7
  • 3
    Uhm... you have to give more information. Obviously you can populate an array by just writing the values like you did. So what do you want to do? Repeat the given elements a certain number of times? Commented Jul 13, 2011 at 15:26
  • 1
    What do you mean by "some general form of doing this"? What is inadequate about these answers? Commented Jul 13, 2011 at 16:48
  • It seems that the answers you have received so fat are not adequate, for you. Well, IMHO they really answered proper manner your question, before you edited it. So, please consider to update your question such a way that it reveals your real problem. Otherwise it is just noise, what you mean by 'general form', which indeed is not needed here. Thanks Commented Jul 13, 2011 at 19:41
  • I hope everything is clear now. =) Commented Jul 13, 2011 at 20:22
  • In my answer, I added an alternative to your code. I don't know if it is general enough, but it gives the same output as your code. But by avoiding loops and using built-in functions, the code is simpler and faster. Commented Jul 13, 2011 at 21:02

5 Answers 5

11

You can use the function tile. From the examples:

>>> a = np.array([0, 1, 2])
>>> np.tile(a, 2)
array([0, 1, 2, 0, 1, 2])

With this function, you can also reshape your array at once like they do in the other answers with reshape (by defining the 'repeats' is more dimensions):

>>> np.tile(a, (2, 1))
array([[0, 1, 2],
 [0, 1, 2]])

Addition: and a little comparison of the difference in speed between the built in function tile and the multiplication:

In [3]: %timeit numpy.array([1, 2, 3]* 3)
100000 loops, best of 3: 16.3 us per loop
In [4]: %timeit numpy.tile(numpy.array([1, 2, 3]), 3)
10000 loops, best of 3: 37 us per loop
In [5]: %timeit numpy.array([1, 2, 3]* 1000)
1000 loops, best of 3: 1.85 ms per loop
In [6]: %timeit numpy.tile(numpy.array([1, 2, 3]), 1000)
10000 loops, best of 3: 122 us per loop 

EDIT

The output of the code you gave in your question can also be achieved as following:

arr = myIter / (N + 1)
X = numpy.repeat(arr, N)
Y = numpy.tile(arr, N)

This way you can avoid looping the arrays (which is one of the great advantages of using numpy). The resulting code is simpler (if you know the functions of course, see the documentation for repeat and tile) and faster.

BenMorel
36.9k52 gold badges208 silver badges339 bronze badges
answered Jul 13, 2011 at 15:29

4 Comments

I like tile better than multiplication since you can do it to numpy vectors :)
For a large number of repetitions, tile is also a lot faster than multiplication.
IS there any way to substitute while loops with Numpy?!
@theSun: I don't think there is a 'general' substitute, but if you have a particular case you can always post it as a question if you think it can be done simpler but don't know how.
1
print numpy.array(range(1, 4) * 3)
print numpy.array(range(1, 5) * 4).astype(float) * 2 / 10
answered Jul 13, 2011 at 15:28

Comments

1

If you want to create lists of repeating values, you could use list/tuple multiplication...

>>> import numpy
>>> numpy.array((1, 2, 3) * 3)
array([1, 2, 3, 1, 2, 3, 1, 2, 3])
>>> numpy.array((0.2, 0.4, 0.6, 0.8) * 3).reshape((3, 4))
array([[ 0.2, 0.4, 0.6, 0.8],
 [ 0.2, 0.4, 0.6, 0.8],
 [ 0.2, 0.4, 0.6, 0.8]])

Thanks for updating your question -- it's much clearer now. Though I think joris's answer is the best one in this case (because it is more readable), I'll point out that the new code you posted could also be generalized like so:

>>> arr = numpy.arange(1, N + 1) / (N + 1.0)
>>> X = arr[numpy.indices((N, N))[0]].flatten()
>>> Y = arr[numpy.indices((N, N))[1]].flatten()

In many cases, when using numpy, one avoids while loops by using numpy's powerful indexing system. In general, when you use array I to index array A, the result is an array J of the same shape as I. For each index i in I, the value A[i] is assigned to the corresponding position in J. For example, say you have arr = numpy.arange(0, 9) / (9.0) and you want the values at indices 3, 5, and 8. All you have to do is use numpy.array([3, 5, 8]) as the index to arr:

>>> arr
array([ 0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
 0.55555556, 0.66666667, 0.77777778, 0.88888889])
>>> arr[numpy.array([3, 5, 8])]
array([ 0.33333333, 0.55555556, 0.88888889])

What if you want a 2-d array? Just pass in a 2-d index:

>>> arr[numpy.array([[1,1,1],[2,2,2],[3,3,3]])]
array([[ 0.11111111, 0.11111111, 0.11111111],
 [ 0.22222222, 0.22222222, 0.22222222],
 [ 0.33333333, 0.33333333, 0.33333333]])
>>> arr[numpy.array([[1,2,3],[1,2,3],[1,2,3]])]
array([[ 0.11111111, 0.22222222, 0.33333333],
 [ 0.11111111, 0.22222222, 0.33333333],
 [ 0.11111111, 0.22222222, 0.33333333]])

Since you don't want to have to type indices like that out all the time, you can generate them automatically -- with numpy.indices:

>>> numpy.indices((3, 3))
array([[[0, 0, 0],
 [1, 1, 1],
 [2, 2, 2]],
 [[0, 1, 2],
 [0, 1, 2],
 [0, 1, 2]]])

In a nutshell, that's how the above code works. (Also check out numpy.mgrid and numpy.ogrid -- which provide slightly more flexible index-generators.)

Since many numpy operations are vectorized (i.e. they are applied to each element in an array) you just have to find the right indices for the job -- no loops required.

answered Jul 13, 2011 at 15:29

Comments

0
import numpy as np 
X = range(1,4)*3
X = list(np.arange(.2,.8,.2))*4

these will make your two lists, respectively. Hope thats what you were asking

answered Jul 13, 2011 at 15:29

Comments

0

I'm not exactly sure what you are trying to do, but as a guess: if you have a 1D array and you need to make it 2D you can use the array classes reshape method.

 >>> import numpy
 >>> a = numpy.array([1,2,3,1,2,3])
 >>> a.reshape((2,3))
 array([[1, 2, 3],
 [1, 2, 3]])
answered Jul 13, 2011 at 15:32

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.