Присвоить значения массиву numpy, используя индексы строк - PullRequest
0 голосов
/ 10 апреля 2020

Предположим, у меня есть два массива, a=np.array([0,0,1,1,1,2]), b=np.array([1,2,4,2,6,5]). Элементы в a означают индексы строки, где b должны быть назначены. И если в одной строке несколько элементов, значения следует назначать по порядку. Таким образом, результатом является двумерный массив c:

c = np.zeros((3, 4))
counts = {k:0 for k in range(3)}
for i in range(a.shape[0]):
    c[a[i], counts[a[i]]]=b[i]
    counts[a[i]]+=1
print(c)

. Есть ли способ использовать какой-нибудь причудливый метод индексации в numpy, чтобы получить такие результаты быстрее (без l для 101 *) в случае эти массивы большие.

1 Ответ

2 голосов
/ 10 апреля 2020

Мне пришлось запустить ваш код, чтобы увидеть, что он на самом деле произвел. Есть пределы тому, что я могу «запустить» в своей голове.

In [230]: c                                                                                            
Out[230]: 
array([[1., 2., 0., 0.],
       [4., 2., 6., 0.],
       [5., 0., 0., 0.]])
In [231]: counts                                                                                       
Out[231]: {0: 2, 1: 3, 2: 1}

Пропуск этой информации может задержать возможные ответы. «Векторизация» требует мышления в терминах целого массива, что проще всего, если я могу визуализировать результат и искать шаблон.

Это похоже на проблему padding.

In [260]: u, c = np.unique(a, return_counts=True)                                                      
In [261]: u                                                                                            
Out[261]: array([0, 1, 2])
In [262]: c                                                                                            
Out[262]: array([2, 3, 1])      # cf with counts

Загрузка данных со строками разных размеров в Numpy массив

Работая из предыдущих вопросов о заполнении, я могу создать маску:

In [263]: mask = np.arange(4)<c[:,None]                                                                
In [264]: mask                                                                                         
Out[264]: 
array([[ True,  True, False, False],
       [ True,  True,  True, False],
       [ True, False, False, False]])

и использовать ее для присвойте b значения c:

In [265]: c = np.zeros((3,4),int)                                                                      
In [266]: c[mask] = b                                                                                  
In [267]: c                                                                                            
Out[267]: 
array([[1, 2, 0, 0],
       [4, 2, 6, 0],
       [5, 0, 0, 0]])

Поскольку a уже отсортировано, мы можем получить счет быстрее, чем с unique. Также у него будут проблемы, если a не имеет значений для некоторых строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...