Faster method of looping through pixels
<p>I'm looping through every pixel of some photos and storing the RGB numbers, plus the location of the pixel.</p>

<p>This is my current loop which looks like it might be a very slow version of what is actually possible - I have some familiarity with pandas hence I've used a dataframe to store the data inside the loop.</p>

<p>What avenues should I explore to make this more efficient? Scrap the df idea and use a vanilla list instead?</p>

<pre><code>import os
import pandas as pd
import numpy as np

from PIL import ImageColor
from PIL import Image
IMAGE_PATH = 'P:/image_files/'

def loopThroughPixels():
    im = Image.open(IMAGE_PATH + 'small_orange_white.png') 
    w,h = im.size

    df = pd.DataFrame({
        'pixLocation' : [(0,0)],
        'pixRGB' : [im.getpixel((0,0))]
        })

    i = 0
    for x in range(w):
        for y in range(h):
                i = i + 1
                new_record = pd.DataFrame({
                    'pixLocation' : [(x,y)],
                    'pixRGB' : [im.getpixel((x,y))]
                    })
                df = pd.concat([df,new_record])
                del new_record

    df.reset_index(inplace = True)
    df.drop("index", axis = 1, inplace = True)
</code></pre>

<hr>

<p>note</p>

<p>Nehal's answer is quick put producing the wrong answer. Let me illustrate:</p>

<pre><code>import pandas as pd
import itertools
from PIL import ImageColor
from PIL import Image

# create  very small image to illustrate
i = Image.new('RGB',(2,2))
i.putpixel((0,0), (1,1,1))
i.putpixel((1,0), (2,2,2))
i.putpixel((0,1), (3,3,3))
i.putpixel((1,1), (4,4,4))

# run the algorithm:
def loopThroughPixels():

    im = i
    w,h = im.size

    pixLocation = list(itertools.product(range(h), range(w)))
    pixRGB = list(im.getdata())

    df = pd.DataFrame({'pixLocation': pixLocation, 'pixRGB': pixRGB})

    return df
</code></pre>

<h1>the result:</h1>

<p><a href="http://i.stack.imgur.com/xfAT3.png" rel="nofollow"><img src="http://i.stack.imgur.com/xfAT3.png" alt="enter image description here"></a></p>

<p>COMPARE THE RESULT TO THE INITIAL putpixel STATEMENTS - THE ALGOITHM IS SAYING COORDINATE (0,1) IS (2,2,2) BUT IT SHOULD BE (3,3,3).</p>

<p>A faster way would be:</p>

<pre><code>import pandas as pd
from PIL import ImageColor
from PIL import Image
IMAGE_PATH = 'P:/image_files/'

def loopThroughPixels():
    im = Image.open(IMAGE_PATH + 'small_orange_white.png')
    w,h = im.size

    pixLocation = [(y, x) for x in range(h) for y in range(w)]
    pixRGB = list(im.getdata())

    df = pd.DataFrame({'pixLocation': pixLocation, 'pixRGB': pixRGB})

    return df

loopThroughPixels()
</code></pre>

<p>On a file of description...</p>

<pre><code>PNG image data, 1399 x 835, 8-bit/color RGBA, non-interlaced
</code></pre>

<p>...it took:</p>

<pre><code>In [1]: %timeit loopThroughPixels()
1 loop, best of 3: 324 ms per loop
</code></pre>

<p>Update (comparison with options from comments):</p>

<pre><code>In [14]: w = 1399

In [15]: h = 835

In [16]: [(y, x) for x in range(h) for y in range(w)] == list(zip(list(range(w))*h, sorted(list(range(h))*w)))
Out[16]: True

In [17]: %timeit  [(y, x) for x in range(h) for y in range(w)]
10 loops, best of 3: 107 ms per loop

In [18]: %timeit  list(zip(list(range(w))*h, sorted(list(range(h))*w)))
1 loop, best of 3: 207 ms per loop
</code></pre>

python pandas