Сначала извлеките элементы непосредственно из списков в каждой ячейке, а не используйте списки длины один:
df = df.applymap(lambda x: x[0])
Теперь создайте декартово произведение вашего DataFrame:
df['key'] = 1
v = df.merge(df, on='key').drop('key', 1)
Наконец, использование numpy.linalg.norm
:
a, b = np.split(v.values, 2, axis=1)
np.linalg.norm(a-b, axis=1)
array([ 0. , 3.78112721, 6.55159408, 9.73626592, 13.05073293,
16.5094545 , 19.08991902, 21.51870493,
...,
3.80204011, 21.87054435, 19.27190362, 17.05360123, 16.66578891,
14.17596917, 15.336336 , 14.12221987, 13.25891979, 11.50788799,
9.1692209 , 5.45392244, 3.80204011, 0. ])
Это довольно интенсивное использование памяти, поскольку для создания декартовой системы требуется O (N ^ 2) памяти.товар.Если это становится проблемой, вы можете создать генератор, который делает то же самое, за счет некоторой скорости:
def lazy_distance(df):
a = df.values
for x in a:
for y in a:
yield np.linalg.norm(x - y)
In [78]: np.array_equal(np.array(list(lazy_distance(df))), np.linalg.norm(a-b, axis=1))
Out[78]: True