开发者

Python NumPy Arrays

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 =开发者_如何学JAVA [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.


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.


print numpy.array(range(1, 4) * 3)
print numpy.array(range(1, 5) * 4).astype(float) * 2 / 10


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.


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


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]])
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜