Рассчитать Манхэттен Расстояние возврата Категория с самым низким расстоянием - PullRequest
0 голосов
/ 03 октября 2018

Я хочу создать функцию, которая вычисляет расстояние Манхэттена между выбранной категорией и всеми другими категориями в наборе данных.Функция должна затем вернуть КАТЕГОРИЮ с наименьшим расстоянием от выбранного.

df = pd.DataFrame(np.random.randint(0,100, size= (10,4)), columns=list('ABCD'))
df['category']= ['apple','orange','grape','berry','strawberry','banana','kiwi','lemon','lime','pear']

Приведенный ниже код возвращает наименьшие 4 расстояния, которые включают выбранную категорию (расстояние = 0; это избыточно и не нужно).Мне нужно, чтобы код возвращал только самые низкие 3 расстояния в виде списка категорий, первая из которых самая маленькая.

def distance(row):
    cols = list('ABCD')
    return (df[cols] - row[cols]).abs().sum(axis=1)

df.set_index('category', inplace=True)
dist = df.apply(distance, axis=1)

dist['apple'].nsmallest(4)

Например, если было выбрано «Apple», а три самых низких расстояния от Apple былиЯгоды, апельсин и виноград, возвращение должно выглядеть так: ["Ягода", "Апельсин", "Виноград"]

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Один из вариантов - использовать функцию cityblock из scipy.spatial.distance:

from scipy.spatial import distance

df.set_index('category', inplace = True)

>> df.apply(lambda x: distance.cityblock(x, df.loc['apple',:]), axis=1
        ).drop('apple', axis=1).nsmallest(4).index.values.tolist()

 ['strawberry', 'berry', 'kiwi', 'orange']

По сути, вы получаете расстояние от каждой строки до выбранной.Затем вы отбрасываете строку, содержащую выбранную метку, и выбираете индекс наименьших расстояний.

0 голосов
/ 03 октября 2018

Настройка:

df = pd.DataFrame(np.random.randint(0,100, size= (10,4)), columns=list('ABCD'))
df['category']= . ['apple','orange','grape','berry','strawberry','banana','kiwi','lemon','lime','pear']
df.set_index('category', inplace = True)

Это глоток, но:

lowest_3 = [df.index[pd.Series([abs(df.loc[ind1] - df.loc[ind2]).sum() for ind2 in df.index]).argsort()[1:4]].tolist() for ind1 in df.index]

lowest_3_series = pd.Series(lowest_3, index = df.index)

lowest_3_series['apple'] = ['banana', 'lemon', 'grape'] # Results will differ due to randomness obviously

Это даст вам список 3 самых низких значений для каждого значения в df.index.

Например, первый элемент этого списка - ваше решение для 'apple'

Объяснение:

Сначала вы создаете понимание списка для каждого индекса в df.index.Это понимание вложенного списка снова является итерациями над df.index.Вы вызываете df для этого индекса и сравниваете их все попарно (всего получается n ^ 2 сравнений).Вы сравниваете каждый индекс, беря абсолютное значение между значениями их столбцов и суммируя их.Затем превратите этот список в серию и используйте argsort, чтобы получить первые 3 (исключая рефлексивное сравнение, которое всегда равно 0).Затем вы вызываете df.index для этой части индексов, которая возвращает вам имена этих самых низких 3 значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...