1

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.

2 Answers 2

1

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]]])
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this works. However in my case the elements of the list are generated by performing bitwise operations on the elements of the array. In particular I have a list containing bits, and I want to change each element of the array to have the bit in the list as LSB.
@FrancescoCarzaniga Important bits like those should be mentioned in the question upfront. Hopefully you would keep that in mind in your future questions. For now, please edit the question with those details and kindly show us more appropriate/representative sample inputs and expected output.
Yes you're right I'm sorry, thanks to your answer however I found a solution for my specific problem. Thank you very much again!
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.