Выполнить среднее значение numpy по матрице, используя метки в качестве индикаторов

import numpy as np    
arr = np.random.random((5, 3))
labels = [1, 1, 2, 2, 3]
arr
Out[136]: 
array([[0.20349907, 0.1330621 , 0.78268978],
       [0.71883378, 0.24783927, 0.35576746],
       [0.17760916, 0.25003952, 0.29058267],
       [0.90379712, 0.78134806, 0.49941208],
       [0.08025936, 0.01712403, 0.53479622]])
labels
Out[137]: [1, 1, 2, 2, 3]

Предположим, что у меня есть этот набор данных. Я хотел бы, используя метки в качестве индикаторов, выполнять np.mean по строкам.

(Здесь метки указывают класс каждой строки. ярлыки тоже могут быть [0, 1, 1, 0, 4, 1, 4] Так что не думайте о них.)

Таким образом, вывод здесь будет средним по:

1st and 2nd row.
3rd and 4th row.
5th row.

Наиболее эффективным способом предлагает numpy. вот так:

[np.mean(arr[:2], axis=0),
np.mean(arr[2:4], axis=0),
np.mean(arr[4:], axis=0)]
Out[180]: 
[array([0.46116642, 0.19045069, 0.56922862]),
 array([0.54070314, 0.51569379, 0.39499737]),
 array([0.08025936, 0.01712403, 0.53479622])]

(в реальном сценарии размеры матрицы могут быть (100000, 256))

Я думаю, что одним из векторизованных способов может быть np.bincount(labels, np.sum(arr, axis = 1)) / (np.bincount(labels) * arr.shape[1])

David Arenburg 10.01.2023 13:37

Bincount будет работать, если метки расположены в порядке возрастания. Я могу заставить это, но есть ли способ без него? например, если бы метки были такими: [0, 1, 1, 0, 4, 1, 4]

Eran Moshe 10.01.2023 13:57

@DavidArenburg Я изменил среднюю ось на 0 .. Сначала я ошибался.

Eran Moshe 10.01.2023 15:10
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
0
3
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не понял часть меток в вашем вопросе. но есть способ вычислить среднее значение каждой строки в матрице. использовать --> np.mean (обр, ось = 1).

Если вы хотите использовать ярлыки, пожалуйста, выполните приведенный ниже скрипт.

import numpy as np
arr = np.array([[1,2,3],
    [4,5,6],
    [7,8,9],
    [1,2,3],
    [4,5,6]])
labels =np.array([0, 1, 1, 0, 4])
#print(arr)
#print('LABEL IS :', labels)
#print('MEAN VALUES ARE : ',np.mean(arr[:2], axis = 1))
id = labels.argsort()
eq_lal = labels[id]
print(eq_lal)
print(arr[eq_lal])
print(np.mean(arr[eq_lal], axis = 1))

Извините, мой друг, но это упускает из виду весь вопрос ..

Eran Moshe 10.01.2023 13:58

Спасибо. поэтому, если я правильно понимаю постановку задачи, вы хотите использовать метки в качестве индикаторов для вычисления среднего значения конкретной строки. пример: [0, 1, 1, 0, 4, 1, 4] в этом случае, если используется «метка 1», означает ли это, что он должен вычислять среднее значение 1-й, 2-й и 5-й строк? Это правильно? Я работаю над решением, поэтому нужно некоторое разъяснение.

Shruthi 10.01.2023 14:26

Да это точно. Но решение не должно использовать циклы for, а исключительно операции numpy.

Eran Moshe 10.01.2023 14:40

Я пробовал, и это работает для меня. Упомянутое ниже решение сначала сортирует порядок меток (по возрастанию) и считывает массив с индекса 0 (ноль).

Shruthi 10.01.2023 16:03

Arr = np.array([[1,2,3], [4,5,6], [7,8,9], [1,2,3], [4,5,6]]) метки = np.array([0, 1, 1, 0, 4]) #print(arr) #print('ЭТИКЕТКА:', метки) #print('СРЕДНИЕ ЗНАЧЕНИЯ: ',np.mean(arr[:2 ], ось = 1)) id = labels.argsort() eq_lal = labels[id] print(eq_lal) print(arr[eq_lal]) print(np.mean(arr[eq_lal], axis = 1))

Shruthi 10.01.2023 16:05

Также см. stackoverflow.com/questions/53166011/…

Shruthi 10.01.2023 16:05

Извините, чувак.. Но это не решает.. Посмотрите на ответ, который я опубликовал.. Это решает.

Eran Moshe 10.01.2023 16:20
Ответ принят как подходящий

Сначала мы хотели бы отсортировать нашу метку и матрицу:

labels = np.array(labels)
# Getting the indices of a sorted array
sorted_indices = np.argsort(labels)
# Use the indices to sort both labels and matrix
sorted_labels = labels[sorted_indices]
sorted_matrix = matrix[sorted_indices]

Затем мы вычисляем «шаги» или пары индексов (от, до), по которым мы хотим вычислить среднее значение. Мы суммируем их и делим на их количество.

# Here we're getting the amount of rows per label to average (over the sorted_matrix). 
# Infact, we're getting the start and end indices per label.
label_indices = np.concatenate(([0], np.where(np.diff(sorted_labels) != 0)[0] + 1, [len(sorted_labels)]))

# using add + reduceat to add all rows with regard to the label indices
group_sums = np.add.reduceat(sorted_matrix, label_indices[:-1], axis=0)
# getting count for each group using the diff in label_indices
group_counts = np.diff(label_indices)
# Calculating the mean
group_means = group_sums / group_counts[:, np.newaxis]

Пример:

matrix
Out[265]: 
array([[0.69524902, 0.22105336, 0.65631557, 0.54823511, 0.25248685],
       [0.61675048, 0.45973729, 0.22410694, 0.71403135, 0.02391662],
       [0.02559926, 0.41640708, 0.27931808, 0.29139379, 0.76402121],
       [0.27166955, 0.79121862, 0.23512671, 0.32568048, 0.38712154],
       [0.94519182, 0.99834516, 0.23381289, 0.40722346, 0.95857389],
       [0.01685432, 0.8395658 , 0.73460083, 0.08056013, 0.02522956],
       [0.27274409, 0.64602305, 0.05698037, 0.23214598, 0.75130743],
       [0.65069115, 0.32383729, 0.86316629, 0.69659358, 0.26667206],
       [0.91971818, 0.02011127, 0.91776206, 0.79474582, 0.39678431],
       [0.94645805, 0.18057829, 0.23292538, 0.93111373, 0.44815706]])

labels
Out[266]: array([3, 3, 2, 3, 1, 0, 2, 0, 2, 5])

group_means 
Out[267]: 
array([[0.33377274, 0.58170155, 0.79888356, 0.38857686, 0.14595081],
       [0.94519182, 0.99834516, 0.23381289, 0.40722346, 0.95857389],
       [0.40602051, 0.36084713, 0.41802017, 0.43942853, 0.63737099],
       [0.52788969, 0.49066976, 0.37184974, 0.52931565, 0.221175  ],
       [0.94645805, 0.18057829, 0.23292538, 0.93111373, 0.44815706]])

И результаты подходят для: np.unique(sorted_labels)

np.unique(sorted_labels)
Out[271]: array([0, 1, 2, 3, 5])

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