Созданная вами функция выглядит как стандартное расстояние городского квартала (Манхэттен), то есть вы можете сделать это с помощью простого вызова функции библиотеки SciPy:
from scipy.spatial.distance import squareform, pdist
dm = pd.DataFrame(squareform(pdist(df, metric='cityblock')), index=df.index, columns=df.index)
Результаты:
John Jen Jo
John 0.0 9.0 18.0
Jen 9.0 0.0 9.0
Jo 18.0 9.0 0.0
См. pdist
и squareform
документацию для получения более подробной информации.
Обратите внимание, что если ваша фактическая функция более сложная, чем в описанном вами Городском блоке, вы описали, все еще возможно использовать эти функции SciPy с пользовательской метрикой расстояния.
Хотя это и не обязательно для этого конкретного случая, вот как можно применить пользовательскую функцию расстояния при необходимости.Сначала создайте функцию, которая принимает две строки в качестве входных данных и возвращает одно число расстояния:
def my_distance_function(row1, row2):
return np.abs(row1 - row2).sum()
Затем применяется следующим образом:
dm = pd.DataFrame(squareform(pdist(df, metric=my_distance_function)), index=df.index, columns=df.index)
Это дает тот же результат, что и 'функция cityblock 'в библиотеке SciPy, но вы можете увидеть, как вы можете настроить ее сейчас, чтобы она соответствовала вашим потребностям при необходимости.