Dzung Nguyen
Dzung Nguyen

Reputation: 3942

Mapping in Python list

I have a list of index stored in a list of tuples:

index=[(0,0), (0,1), (1,0), (1,1) ....]

These indexes will be used to calculate energy in an image im (a numpy array) in the following formula:

(1-im[0,0])^2+(1-im[0,1])^2+....

im here is a two dimensional numpy array. Here's an example of im:

im=Image.open('lena_noisy.png')
im=numpy.array(im)
print im

[[168 133 131 ..., 127 213 107]
 [174 151 111 ..., 191  88 122]
 [197 173 143 ..., 182 153 125]
 ..., 
 [ 34  15   6 ..., 111  95 104]
 [ 37  15  57 ..., 121 133 134]
 [ 49  39  58 ..., 115  74 107]]

How to use map function of list to perform this calculation?

Upvotes: 3

Views: 999

Answers (3)

unutbu
unutbu

Reputation: 880927

If you break index into two tuples, xidx and yidx then you can use fancy indexing to access all the im values as one numpy array. Then the calculation becomes simple to express, and faster than doing a Python loop (or list comprehension):

import numpy as np
xidx, yidx = zip(*index)
print(((1-im[xidx, yidx])**2).sum())

import numpy as np
import scipy.misc as misc

im = misc.lena()
n = min(im.shape)
index = np.random.randint(n, size = (10000,2)).tolist()

def using_fancy_indexing(index, im):
    xidx, yidx = zip(*index)
    return (((1-im[xidx, yidx])**2).sum())

def using_generator_expression(index, im):
    return sum(((1 - im[i[0], i[1]]) ** 2) for i in index)

Here is a comparison using timeit:

In [27]: %timeit using_generator_expression(index, im)
100 loops, best of 3: 17.9 ms per loop

In [28]: %timeit using_fancy_indexing(index, im)
100 loops, best of 3: 2.07 ms per loop

Thus, depending on the size of index, using fancy indexing could be 8x faster than using a generator expression.

Upvotes: 4

Óscar López
Óscar López

Reputation: 236150

Like this, using a generator expression:

sum((1-im[i][j])**2 for i, j in index)

That is, assuming that im is a two-dimensional list and index is a list of coordinates in im. Notice that in Python, a two-dimensional list is accessed like this: m[i][j] and not like this: m[i,j].

Upvotes: 2

Peter Graham
Peter Graham

Reputation: 11701

Using sum and a generator expression:

sum(((1 - im[i[0], i[1]]) ** 2) for i in index)

If index is also a numpy array you can use the array as an index:

sum(((1 - im[i]) ** 2) for i in index)

Upvotes: 1

Related Questions