Элегантная индексация 2D numpy с несколькими условиями - PullRequest
0 голосов
/ 04 марта 2020

У меня есть массив чисел, которые я буду sh превратить в фиктивные переменные (т. Е. Массивы с 1, если условие выполнено, с 0, если иначе). Тем не менее, условия могут быть многочисленными, и мне было интересно, было ли более элегантное решение, чем то, что я использую.

arr = np.random.randint(0, 50, size=(100, 100))

# What I'm doing

dummy = np.zeros(arr.shape)
dummy[np.where(np.logical_or.reduce((arr== 10, arr== 15, arr==16, arr==17)))] = 1

В этом примере каждое значение, равное 10, 15, 16 или 17 становится один ноль. Для некоторых фиктивных переменных у меня более 10 условий, и выражение может быть длинным, поэтому я ищу что-то более чистое. Я пытался что-то вроде этого, но получил ValueError.

dummy= [1 if x in [10, 15, 16, 17] else 0 for x in arr]

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

Вы можете использовать np.select

arr = np.select([arr==10, arr==15,arr==16,arr==17],[1,1,1,1],0)
1 голос
/ 05 марта 2020

Читаемость немного интересна для наблюдателя, но два различных способа использования конструкции 1 in ... else 0 - это использование двойного for l oop над элементами строк матрицы как

dummy = [[1 if x in [10, 15, 16, 17] else 0 for x in row] for row in arr]

Вывод это не np.array (матрица), а скорее list из list с. Другой способ сделать это, который «скрывает» двойной for l oop, состоит в использовании np.vectorize в качестве

dummy_func = np.vectorize(lambda x: 1 if x in [10, 15, 16, 17] else 0)
dummy = dummy_func(arr)

или в качестве однострочного в качестве

dummy = np.vectorize(lambda x: 1 if x in [10, 15, 16, 17] else 0)(arr)

Из этих I вероятно go для векторизованного подхода сохранить тип данных как np.array, поскольку это чаще всего более разумный выбор. И даже если бы я показывал это как одну строку, я все равно думал бы, что было бы лучше сначала определить функцию, а затем применить ее к двум различным строкам.

Следует отметить, что векторизация в основном это просто двойная for l oop, поэтому выполнение выполняется довольно медленно по сравнению с другими numpy функциями. Я не удивлюсь, если есть и другие способы, которые могут использовать встроенное параллельное вычислительное поведение numpy, но тогда это снова компромисс между читаемостью (намерением) и скоростью.

...