Учитывая выходные данные numpy.where(), как получить список списка индексов

#python #arrays #numpy #sparse-matrix

#python #массивы #numpy #разреженная матрица

Вопрос:

Я ищу довольно большую матрицу для нулевых элементов, а затем хочу затем перебирать строки и внутри каждой строки, в целом индексы, где я нашел ноль. numpy.where(M==0) дает мне (np.array, np.array) .

Как я могу отформатировать этот результат в соответствии с моими потребностями наиболее эффективным способом?

 # Output of numpy.where(M==0):
(x,y) = (array([0, 0, 1, 1, 2]), array([2, 3, 1, 2, 1]))
# Output I want, each value of y in the list corresponding to the x value:
wanted = [[2,3],[1,2],[1],[]]
 

Я думал о построении разреженной матрицы из выходных данных (поскольку M она плотная, M==0 должна быть разреженной), но не знаю, как я буду перебирать там строки.

 zeros = scipy.sparse.coo_matrix((np.ones((len(x),)), (x,y)), shape=M.shape)
print(zeros.nonzero()) # is the same output as np.where, so it does not help me
 

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

Редактировать: в качестве альтернативы, словарь формы {x_value:[list of corresponding y_values]} также будет работать

Комментарии:

1. не могли бы вы подробнее рассказать о том, как wanted получаются значения?

2. они не получены, они являются примером формата, в котором я хотел бы получить свои значения: в каждой строке i есть список wanted [i], содержащий индексы столбцов, для которых он равен нулю

3. Посмотрите argwhere , что только что делает np.transpose(np.nonzero(...))1 . Плоская итерация для этого 2d-массива так же хороша (или плоха), как и предлагаемый вами двойной цикл.

4. @hpaulj второй цикл for будет в функции, поскольку мне нужно загружать из базы данных для каждой строки, и из-за этого я хотел бы сгруппировать их по строкам

5. Просто выполните итерацию по индексам строк. Пока они остаются неизменными, соберите значения столбцов в список. Когда они изменяются, вызовите функцию столбца с этим списком.

Ответ №1:

Я обнаружил, что collections.defaultdict это позволило мне преобразовать мои кортежи в dict, как я хотел.

 indices = np.argwhere(M==0)
zeros = defaultdict(list)
for coords in indices:
    zeros[coords[0]].append(coords[1])
print(zeros)
 
 # Output:
defaultdict(<class 'list'>, {0: [1], 1: [1, 2], 2: [0, 3]})