Francesco Carzaniga
Francesco Carzaniga

Reputation: 135

Python numpy array merging manipulation

I am currently using Pillow to access every pixel of an image and to substitute the RGB values with the elements of a list.

I think however that this method is quite slow and I read that a much faster way of doing it is to use numpy arrays.

I convert the image to a numpy array with shape (x, y, 3), but I don't know how to 'merge' it with my list. For example I have a list with 20 elements, so I want to substitute the first 20 elements in my array with those in my list, without changing the shape of my array.

My array looks like this:

[[[121, 222, 222], [1, 1, 1],...]]

And I have a list such as:

[120, 99, 0, 88, 78, 32, 123,...]

The final array should look like this:

[[[120, 99, 0], [88, 78, 32], [123, ..., ...],...]]

The list is shorter that the array, so when the list ends the elements of the array that follow should remain unchanged.

I tried to explain as better as I could, is something is unclear please let me know.

Thank in advance.

Upvotes: 1

Views: 74

Answers (2)

Divakar
Divakar

Reputation: 221524

With a as the array and L as the list, you could simply get a flattened view of the array with np.ravel() and assign values from L by slicing into it, like so -

a.ravel()[:len(L)] = L

Alternatively, we could use np.put that would get the flattened view implicitly and assign it for you, like so -

np.put(a, range(len(L)), L)

If I have to choose, I would go with the ravel() method as it avoids the need for range by using slicing instead.

Sample run -

In [51]: a
Out[51]: 
array([[[91, 18, 74],
        [49, 92, 93],
        [42, 38, 41],
        [27, 24, 69]],

       [[14, 72, 49],
        [85, 74, 45],
        [32, 88, 89],
        [12, 85, 60]]])

In [52]: L = [120, 99, 0, 88, 78, 32, 123]

In [53]: a.ravel()[:len(L)] = L

In [54]: a
Out[54]: 
array([[[120,  99,   0],
        [ 88,  78,  32],
        [123,  38,  41],
        [ 27,  24,  69]],

       [[ 14,  72,  49],
        [ 85,  74,  45],
        [ 32,  88,  89],
        [ 12,  85,  60]]])

Upvotes: 1

Carles Mitjans
Carles Mitjans

Reputation: 4866

A very easy solution is to use list comprehension. Take a look at this:

Assuming lst is the list

lst = [120, 99, 0, 88, 78, 32, 123, 1, 2]
np.array([lst[x:x+3] for x in range(0, len(lst), 3)])

Output:

array([[120,  99,   0],
       [ 88,  78,  32],
       [123,   1,   2]])

Upvotes: 0

Related Questions