Как создать матрицу на основе бинов?

У меня есть набор значений от 3 до 27, которые имеют 20 конечных значений:

A = [(0,21),(1,12),(2,15),(3,3),(4,21),(5,15),(6,27),(7,21),(8,9),(9,27),(10,12),(11,9),(12,12),(13,3),(14,9),(15,12),(16,6),(17,3),(18,9),(19,15)]

Я хотел бы узнать, как создать массив numpy, который будет иметь 9 ячеек, каждая из которых имеет диапазон целых чисел -1 и +1 для заданных кортежей [1], кратных 3 из диапазона 3-27 (но это должно быть взаимозаменяемо с любой другой комбинацией целых чисел и диапазона). В конце концов, я хотел бы иметь возможность создать матрицу, которая выглядит примерно так:

[[0,0,0,0,0,0,1,0,0],
 [0,0,0,1,0,0,0,0,0],
 [0,0,0,0,1,0,0,0,0],
 [1,0,0,0,0,0,0,0,0],
 [0,0,0,0,0,0,1,0,0],
 [0,0,0,0,1,0,0,0,0],
 [0,0,0,0,0,0,0,0,1],
 ....]

Я читал о том, как у numpy есть (num, bins) = histogram(x, bins=None, range=None), но я не совсем уверен, как это сделать.

Я думал, что мне придется перебирать «A», чтобы получить уникальные значения («a»), а затем выполнить диапазон (a-1, a + 1), чтобы получить количество ячеек, которые я бы просто len(unique_values) . Но тогда я потерян. Кто-нибудь может мне помочь?


person Daniel    schedule 28.09.2017    source источник


Ответы (1)


Вот один из способов с np.searchsorted/np.digitize -

bins = np.arange(3,28,3)
ar = np.asarray(A)[:,1] # or np.array([i[1] for i in A])
ids = np.searchsorted(bins, ar) # or np.digitize(ar,bins)-1
out = (ids[:,None] == np.arange(9)).astype(int)

Последний шаг для получения окончательного вывода можно заменить инициализацией массива —

out = np.zeros((len(ids), 9),dtype=int)
out[np.arange(len(ids)), ids] = 1

Если бы первый элемент в кортежах не был в последовательности, мы могли бы использовать их для индексации строк -

out[np.asarray(A)[:,0], ids] = 1

Пробный запуск -

In [205]: A
Out[205]: 
[(0, 21),
 (1, 12),
 (2, 15),
 (3, 3),
 (4, 21),
 (5, 15),
 (6, 27),
 (7, 21),
 (8, 9),
 (9, 27),
 (10, 12),
 (11, 9),
 (12, 12),
 (13, 3),
 (14, 9),
 (15, 12),
 (16, 6),
 (17, 3),
 (18, 9),
 (19, 15)]

In [206]: out[:7] # first 7 rows of output
Out[206]: 
array([[0, 0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1]])
person Divakar    schedule 28.09.2017
comment
Идеальный ответ! Спасибо!! - person Daniel; 28.09.2017