Numpy индексация с использованием массива логических - PullRequest
1 голос
/ 15 октября 2019

У меня есть следующий массив, который указывает, брать или нет определенный элемент:

import numpy as np

test_array = np.array([[0, 0, 1],
                       [1, 1, 0],
                       [1, 1, 1]])

Массив, который я хочу проиндексировать, это:

classes = ['a', 'b', 'c']

Вот чторезультат должен быть:

[['c'], ['a', 'b'], ['a', 'b', 'c']]

Как это можно сделать?

Ответы [ 6 ]

1 голос
/ 15 октября 2019

Ответы, которые я видел до сих пор, варьируются от неловких до, откровенно говоря, сбивающих с толку, так что вот простое решение.

import np

arr = np.array([[0, 0, 1], [1, 1, 0], [1, 1, 1]])

arr_bools = arr.astype(np.bool)

lookup_lst = np.array(['a', 'b', 'c'])

res = [lookup_lst[row].tolist() for row in arr_bools]
1 голос
/ 15 октября 2019

Это можно сделать умножением матрицы:

[*map(list, test_array.astype('O')@classes)]
# [['c'], ['a', 'b'], ['a', 'b', 'c']]
1 голос
/ 15 октября 2019

В одной строке вы можете сделать:

print ([[c for (x, c) in zip(l, classes) if x] for l in test_array])
1 голос
/ 15 октября 2019

Я бы сделал это так:

result = []
for array in test_array:
     result.append([classes[i] for i,value in enumerate(array ) if value ])
1 голос
/ 15 октября 2019

Вы можете сделать следующее:

import numpy as np

test_array = np.array([[0, 0, 1],
                       [1, 1, 0],
                       [1, 1, 1]])

classes = ['a', 'b', 'c']

lookup = dict(enumerate(classes))
result = [[lookup[i] for i, e in enumerate(arr) if e] for arr in test_array]
print(result)

Вывод

[['c'], ['a', 'b'], ['a', 'b', 'c']]
1 голос
/ 15 октября 2019

Я бы начал с чего-то такого:

result = []
for row in test_array:
    partial_result = []
    for i in range(3):
        if row[i] == 1:
            partial_result.append(classes[i])
    result.append(partial_result)
print(result)

Результаты с:

[['c'], ['a', 'b'], ['a', 'b', 'c']]

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

print([[classes[i] for i, val in enumerate(row) if val] for row in test_array])

enumerate - это встроенная функция, которая принимает итерируемый объект в качестве параметра и возвращает итерируемое из кортежей (индекса, элемента) для всех элементов в исходной итерируемой, поэтому enumerate(row) вернет(0, [0, 0, 1]), (1, [1, 1, 0]) и (2, [1, 1, 1]).

for i, val in enumerate(row) if val будет работать, потому что 1s интерпретируется как True в Python и 0s как False.

[[classes[i] for i, val in enumerate(row) if val] for row in test_array]
^ create a list of elements based on some original list ------->^
 ^ each element of that list will be a list itself.
      ^ elements of that inner lists will be objects from classes list
              ^ for each pair (i, element) from enumerate(row) take this ith
                element, but just if val == 1 ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...