Python NumPy попарно редактировать расстояние
Итак, у меня есть небольшой массив строк, и я хочу рассчитать попарно расстояние редактирования между каждой парой элементов, используя эту функцию: scipy.spatial.distance.pdist from http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.spatial.distance.pdist.html
Пример моего массива выглядит следующим образом:
>>> d[0:10]
array(['TTTTT', 'ATTTT', 'CTTTT', 'GTTTT', 'TATTT', 'AATTT', 'CATTT',
'GATTT', 'TCTTT', 'ACTTT'],
dtype='|S5')
Тем не менее, поскольку у него нет опции 'editdistance ', поэтому я хочу дать настраиваемую функцию расстояния. Я попробовал это, и я столкнулся со следующей ошибкой:
>>> 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
2 ответа
Если вы действительно должны использовать pdist
Сначала вам нужно конвертировать ваши строки в числовой формат. Если вы знаете, что все строки будут одинаковой длины, вы можете сделать это довольно легко:
numeric_d = d.view(np.uint8).reshape((len(d),-1))
Это просто рассматривает ваш массив строк как длинный массив uint8
байты, затем изменяет его так, что каждая исходная строка находится в строке отдельно. В вашем примере это будет выглядеть так:
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)
Затем вы можете использовать pdist
как обычно. Просто убедитесь, что ваш editdist
Функция ожидает массивы целых чисел, а не строк. Вы можете быстро конвертировать ваши новые входы, позвонив .tostring()
:
def editdist(x, y):
s1 = x.tostring()
s2 = y.tostring()
... rest of function as before ...
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