2013-02-06 106 views
3

我具有存儲在元組的列表索引的列表:映射在Python列表

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

這些索引將被用於計算能量圖像im的(a numpy的陣列)在以下公式中:

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

im這裏是一個二維numpy數組。下面是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]] 

如何使用列表的地圖功能來執行此計算?

+0

這是一個2維numpy數組,就像查找表一樣。 –

回答

1

使用sum和發電機表達式:

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

如果索引也是numpy的陣列可以使用陣列作爲指標:

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

像這樣,使用生成的表達式:

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

也就是說,假設im是一個二維列表和indexim座標的列表。請注意,在Python中,二維列表的訪問方式如下所示:m[i][j]而不是像這樣:m[i,j]

+0

值得注意的是,您可以將元組解開爲迭代的一部分,而不是索引:'sum((1-im [i] [j])** 2 for i,j in index)''。 – Blckknght

+0

@Blckknght你是對的,這更清楚。我更新了我的答案,謝謝! –

4

如果斷開index成兩個元組,xidxyidx,那麼你可以使用花哨的索引來訪問所有的im值作爲一個numpy數組。 然後計算變得簡單來表達,和比做一個Python循環(或列表解析)更快:

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) 

這裏使用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 

因此,根據index的大小,使用花式索引比使用生成器表達式快8倍。