Я пытаюсь использовать np.where в цифровой матрице MxN, где я хочу вернуть такое же количество строк M, но индексы в каждой строке, где существует элемент. Возможно ли это сделать? Например:
a = [[1 ,2, 2]
[2, 3, 5]]
np.where(a == 2)
Я хотел бы, чтобы это вернулось:
[[1, 2],
[0]]
Спасибо. Я думаю, вы имеете в виду np.where(row == 2)[1]
в своем ответе вместо np.where(row == 2)[0]
Нет, я имею в виду np.where(row == 2)[0]
; это потому, что каждый результат вызоваwhere возвращает кортеж. В данном случае это кортеж из одного элемента, и мы хотим получить первый (и единственный) элемент.
Попробуйте следующее: a = np.asarray([[1, 2, 2], [2, 3, 5]]); print([np.where(row == 2)[0].tolist() for row in a])
Понял, спасибо! В качестве дополнительного вопроса: могу ли я использовать этот результат для подмножества другой матрицы (те же размеры, что и результат np.where)? Причина в том, что я хочу рассчитать некоторую статистику для каждой строки (среднее значение, стандартное значение и т. д.).
Ну собственно для этого и создан результат np.where
. Если у вас есть другой массив MxN, скажем b = np.arange(6).reshape(2, 3)
, вы можете сделать b[np.where(a==2)]
. Но ещё короче можно было бы написать b[a==2]
.
Но это выбирает все элементы в один массив, если я не ошибаюсь. Мне все еще нужно иметь M строк.
Я думаю, ответ @mozway вас покрыл :)
Один из вариантов — постобработка вывода где , а затем разделить:
a = np.array([[1, 2, 2],
[2, 3, 5]])
i, j = np.where(a == 2)
out = np.split(j, np.diff(i).nonzero()[0]+1)
Альтернативно, используя понимание списка:
out = [np.where(x==2)[0] for x in a]
Выход:
[array([1, 2]), array([0])]
a = np.array([[1, 2, 2], [2, 3, 5]])
b = np.array([[10, 20, 30], [40, 50, 60]])
m = a == 2
i, j = np.where(m)
# (array([0, 0, 1]), array([1, 2, 0]))
idx = np.r_[0, np.diff(i).nonzero()[0]+1]
# array([0, 2])
out = np.add.reduceat(b[m], idx)/np.add.reduceat(m[m], idx)
# array([50, 40])/array([2, 1])
Выход:
array([25., 40.])
a = np.array([[1, 2, 2], [2, 3, 5]])
b = np.array([[10, 20, np.nan], [40, 50, 60]])
m = a == 2
i, j = np.where(m)
# (array([0, 0, 1]), array([1, 2, 0]))
idx = np.r_[0, np.diff(i).nonzero()[0]+1]
# array([0, 2])
b_m = b[m]
# array([20., nan, 40.])
nans = np.isnan(b_m)
# array([False, True, False])
out = np.add.reduceat(np.where(nans, 0, b_m), idx)/np.add.reduceat(~nans, idx)
# array([20., 40.])/array([1, 1])
Выход:
array([20., 40.])
Очень полезно, спасибо. Как я писал в комментариях выше, есть ли способ выбрать элементы по строке другой матрицы, используя «выходные» значения из вашей функции?
@KidSudi, можешь привести пример? (вход + ожидаемый результат)
так скажем так b = np.array([[10, 20, 30], [40, 50, 60]])
. Я хочу, чтобы среднее значение каждой строки матрицы выбранных элементов использовало «выходные» значения, т. е. np.array([25, 40])
.
@KidSudi Понятно, это непросто (это мог быть другой вопрос), на самом деле лучше использовать другой метод без списка индексов, см. обновление.
очень круто, спасибо за этот метод. Итак, похоже, что мы не можем использовать np.mean
здесь для моего примера - на самом деле я собирался использовать np.nanmean
, что может быть невозможно в этом решении?
Ну можно, но без nanmean, см. обновление (это определенно должен был быть другой вопрос) ;)
Большое спасибо. Согласен - обязательно должен быть в другом вопросе. У меня есть еще один, который я опубликую отдельно, но связанный :)
Я добавил продолжение здесь: stackoverflow.com/questions/78751642/…
На самом деле я сравнил это с написанной мной версией pandas и заметил, что есть много ошибок, особенно в начале набора данных (это временной ряд данных, содержащий около 100 000 строк и 1000 столбцов). Есть ли что-то, что мне здесь не хватает? Почему может быть такое несоответствие?
ваш ввод представляет собой массив с плавающей запятой?
Да, входные данные представляют собой массив float64.
тогда np.diff(i).nonzero()
может работать неправильно, отображая арифметику с плавающей запятой, вместо этого вам следует установить пороговое значение.
Без использования явного цикла
for
такого решения, скорее всего, не существует. Проблема здесь в том, что каждая строка ожидаемого результата может иметь произвольную длину. С другой стороны, функции NumPy обычно оптимизируются для данных регулярной структуры (например, входных данных). Если вас устраивает петляfor
, то, конечно, можно просто применятьnp.where()
отдельно в каждом ряду. Например, вы можете использоватьresult = [np.where(row == 2)[0].tolist() for row in a]