Вернуть максимальное значение каждой строки с именем кластера в фрейме данных

У меня есть фрейм данных pandas (df), который имеет три столбца (пользователь, значения и имя группы), столбец значений с несколькими значениями, разделенными запятыми, в каждой строке.

df = pd.DataFrame({'user': ['user_1', 'user_2', 'user_3', 'user_4', 'user_5',  'user_6'],
                   'values': [[1, 0, 2, 0], [1, 8, 0, 2],[6, 2, 0, 0], [5, 0, 2, 2], [3, 8, 0, 0],[6, 0, 0, 2]],
                   'group': ['B', 'A', 'C', 'A', 'B', 'B']})
df

вывод:

user    values  group
0   user_1  [1, 0, 2, 0]    B
1   user_2  [1, 8, 0, 2]    A
2   user_3  [6, 2, 0, 0]    C
3   user_4  [5, 0, 2, 2]    A
4   user_5  [3, 8, 0, 0]    B
5   user_6  [6, 0, 0, 2]    B

Затем я вычисляю среднее значение каждого кластера, который называется центроидом в фрейме данных (df1).

df1 = (df.groupby('group', as_index=False)['values']
         .agg(lambda x: np.vstack(x).mean(0).round(2))
       )
df1

Вывод:

group   values
0   A   [3.0, 4.0, 1.0, 2.0]
1   B   [3.33, 2.67, 0.67, 0.67]
2   C   [6.0, 2.0, 0.0, 0.0]

Наконец, я вычисляю среднее расстояние от каждого пользователя до всех кластеров в следующем коде, используя евклидово расстояние.

for value in df['values']:
    distance_values = []
    for centroid in df1['values']:
        distance_values.append(distance.euclidean(value, centroid))
    print(distance_values)

Вывод:

[5.0, 3.8439042651970405, 5.744562646538029]
[4.58257569495584, 6.004631545732011, 8.06225774829855]
[4.242640687119285, 2.9112883745860696, 0.0]
[4.58257569495584, 3.668187563361503, 3.605551275463989]
[4.58257569495584, 5.4236150305861495, 6.708203932499369]
[5.0990195135927845, 4.059014658756482, 2.8284271247461903]

Итак, для каждого пользователя я рассчитываю среднее расстояние до центра тяжести каждого кластера. Например:
Для user_1 среднее расстояние до кластеров A=5,0, B=3,8439042651970405 и C=5,744562646538029.

Как вернуть максимальное значение каждой строки в значениях расстояния с именем его кластера в фрейме данных?

Например, ожидаемый результат:

user             max_value    group
0   user_1  5.744562646538029   C
1   user_2  8.06225774829855    C
2   user_3  4.242640687119285   A
3   user_4  4.58257569495584    A
4   user_5  6.708203932499369   C
5   user_6  5.0990195135927845  A
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
72
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать apply для извлечения максимальных значений с их индексами. а затем используйте основные манипуляции со строками:

df['distance_values'] = [[5.0, 3.8439042651970405, 5.744562646538029],
[4.58257569495584, 6.004631545732011, 8.06225774829855],
[4.242640687119285, 2.9112883745860696, 0.0],
[4.58257569495584, 3.668187563361503, 3.605551275463989],
[4.58257569495584, 5.4236150305861495, 6.708203932499369],
[5.0990195135927845, 4.059014658756482, 2.8284271247461903]]  

max_df = df['distance_values'].apply(lambda x: [max(x), x.index(max(x))])
df['max_value'] = max_df.str[0]
df['group'] = max_df.str[1].map(dict(zip(range(4), 'ABC')))

@ Нури Таш, могу ли я хранить и сохранять (distance_values) и (max_df) в отдельных фреймах данных? для простоты использования и интерпретации?

aam 16.11.2022 14:08
Ответ принят как подходящий
max_dist_idx = []
distant_cluster = []

for value in df['values']:
    distance_values = []

    for centroid in df1['values']:
        distance_values.append(distance.euclidean(value, centroid))

    max_dist_idx.append(max(distance_values))
    distant_cluster.append(distance_values.index(max(distance_values)))

cluster_map = {0: 'A', 1: 'B', 2: 'C'}
max_group = [cluster_map[i] for i in distant_cluster]

то вы можете просто смонтировать свой фрейм данных:


pd.DataFrame(data = {'user': df.user,
                   'max_value': max_dist_idx,
                   'group': max_group})

   user     max_value    group
0  user_1   5.744563     C
1  user_2   8.062258     C
2  user_3   4.242641     A
3  user_4   4.582576     A
4  user_5   6.708204     C
5  user_6   5.099020     A

Вы также можете включить вычисление евклидова расстояния в функцию, которую вы будете применять для большей эффективности:

def calc_max_dist(value):
    dist_series = df1['values'].apply(lambda x: distance.euclidean(value, x))
    return dist_series.max(), df1[dist_series == dist_series.max()]['group'].values

df[['max_value', 'closest_group(s)']] = pd.DataFrame(df['values'].apply(calc_max_dist).tolist())

Вывод:

     user        values group  max_value closest_group(s)
0  user_1  [1, 0, 2, 0]     B   5.744563              [C]
1  user_2  [1, 8, 0, 2]     A   8.062258              [C]
2  user_3  [6, 2, 0, 0]     C   4.242641              [A]
3  user_4  [5, 0, 2, 2]     A   4.582576              [A]
4  user_5  [3, 8, 0, 0]     B   6.708204              [C]
5  user_6  [6, 0, 0, 2]     B   5.099020              [A]

Другие вопросы по теме