2015-02-13 20 views
6

Neden böyle bir veri dizisi listesi kullanarak ndarray'ı dizine ekleyemiyorum?Sayısal listeyi tuple listesiyle eşitleme

idx = [(x1, y1), ... (xn, yn)] 
X[idx] 

Onun yerine

idx2 = numpy.array(idx) 
X[idx2[:, 0], idx2[:, 1]] # or more generally: 
X[tuple(numpy.vsplit(idx2.T, 1)[0])] 

daha basit, daha pythonic yolu var mı gibi hantal bir şey yapmak zorunda?

cevap

13

Bir tupl listesi kullanabilirsiniz, ancak bu sözleşme istediğinizden farklıdır. numpy, satır endekslerinin bir listesini ve ardından sütun değerlerinin bir listesini bekler. Görünüşe göre, (x, y) çiftlerinin listesini belirtmek istersiniz.

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing Dokümantasyondaki ilgili bölüm 'tamsayı dizisi indekslemesi' dir.


2d dizisinde 3 nokta aramak için bir örnek. (2d 2 puan kafa karıştırıcı olabilir):

In [223]: idx 
Out[223]: [(0, 1, 1), (2, 3, 0)] 
In [224]: X[idx] 
Out[224]: array([2, 7, 4]) 

endeksleri xy çiftlerinin stil kullanılarak:

In [230]: idx1 = [(0,2),(1,3),(1,0)] 
In [231]: [X[i] for i in idx1] 
Out[231]: [2, 7, 4] 

In [240]: X[tuple(np.array(idx1).T)] 
Out[240]: array([2, 7, 4]) 

X[tuple(zip(*idx1))] dönüşüm yaparak başka bir yoludur. Python2'de tuple() isteğe bağlıdır. zip(*...), bir liste listesinin yuvalanmasını tersine çeviren bir Python deyimidir.

Sen ile doğru yolda şunlardır:

In [242]: idx2=np.array(idx1) 
In [243]: X[idx2[:,0], idx2[:,1]] 
Out[243]: array([2, 7, 4]) 

Benim tuple() adildir biraz daha kompakt (ve mutlaka daha 'pythonic'). numpy sözleşmesi verildiğinde, bir çeşit dönüşüm gereklidir.

(N-boyutları ve m-noktaları ile nelerin işe yarayıp yaramadığını kontrol etmeliyiz?)