2014-06-06 17 views
5

, ben dizeleri bir numpy dizi var ve bu işlevi kullanarak öğelerin her çifti arasında ikili düzenleme-mesafe hesaplamak istiyorum: http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.spatial.distance.pdist.htmlpiton Yani numpy ikili düzenleme mesafeli

gelen scipy.spatial.distance.pdist

>>> d[0:10] 
array(['TTTTT', 'ATTTT', 'CTTTT', 'GTTTT', 'TATTT', 'AATTT', 'CATTT', 
    'GATTT', 'TCTTT', 'ACTTT'], 
    dtype='|S5') 

Ancak, 'editdistance' seçeneğini olmadığı için bu nedenle, ben özelleştirilmiş mesafe fonksiyonu vermek istiyorum, şu şekildedir: benim dizinin

bir örneğidir. Bu çalıştı ve aşağıdaki hatayı karşı karşıya:

>>> import editdist 
>>> import scipy 
>>> import scipy.spatial 
>>> scipy.spatial.distance.pdist(d[0:10], lambda u,v: editdist.distance(u,v)) 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/epd-7.3.2/lib/python2.7/site-packages/scipy/spatial/distance.py", line 1150, in pdist 
    [X] = _copy_arrays_if_base_present([_convert_to_double(X)]) 
    File "/usr/local/epd-7.3.2/lib/python2.7/site-packages/scipy/spatial/distance.py", line 153, in _convert_to_double 
    X = np.double(X) 
ValueError: could not convert string to float: TTTTT 
+0

görünüyor. https://docs.python.org/2/library/difflib.html – Pavel

+0

'a bakmak isteyebilirsiniz. Bu hata satırı 'pdist'de 2. satırdır. Böylece dizelerinizi bir sayıya dönüştürerek "pdist" e dönüştürmelisiniz. Ayrıca 'pdist' 2B dizi ister. – hpaulj

cevap

4

Gerçekten pdist kullanmanız gerekiyorsa, önce sayısal formata Dizelerinizi dönüştürmek gerekir. Tüm dizeleri aynı uzunlukta olacağını biliyorsanız, yerine kolayca yapabilirsiniz: Bu sadece uint8 bayt uzun dizi olarak dizeleri dizinizi görür

numeric_d = d.view(np.uint8).reshape((len(d),-1)) 

, o zaman her bir orijinal dize olacak şekilde yeniden şekillendirir kendi başına üst üste. her zamanki gibi

In [18]: d.view(np.uint8).reshape((len(d),-1)) 
Out[18]: 
array([[84, 84, 84, 84, 84], 
     [65, 84, 84, 84, 84], 
     [67, 84, 84, 84, 84], 
     [71, 84, 84, 84, 84], 
     [84, 65, 84, 84, 84], 
     [65, 65, 84, 84, 84], 
     [67, 65, 84, 84, 84], 
     [71, 65, 84, 84, 84], 
     [84, 67, 84, 84, 84], 
     [65, 67, 84, 84, 84]], dtype=uint8) 

Sonra pdist kullanabilirsiniz: sevdiği örnekte, bu olmazdı. Sadece editdist işlevinizin dizgeden ziyade tamsayı dizileri beklediğinden emin olun. Hızlı bir şekilde .tostring() arayarak yeni girişler dönüştürebilirsiniz: bu sadece dizeleri için tasarlanmamış gibi

def editdist(x, y): 
    s1 = x.tostring() 
    s2 = y.tostring() 
    ... rest of function as before ... 
+2

... ya da 'uint8's üzerindeki düzenleme mesafesini doğrudan yapın. – eickenberg

-4

def my_pdist(data,f): 
 
    N=len(data) 
 
    matrix=np.empty([N*(N-1)/2]) 
 
    ind=0 
 
    for i in range(N): 
 
     for j in range(i+1,N): 
 
      matrix[ind]=f(data[i],data[j]) 
 
      ind+=1 
 
    return matrix

+3

Bu sorunun cevabının nasıl olduğuna dair bazı bağlam, ek bilgi sağlamak, yalnızca sorunun orijinal sorumlusu için değil, aynı zamanda bu çözümün gelecekteki ziyaretçileri için de yararlı ve faydalı olacaktır. Ham, "yalnızca kod" snippet'i, bir yanıtın en iyi şekli değildir. – gravity