Необычная индексация для numpy arrary

#python #numpy

Вопрос:

Я хочу взять образец len(valid_frame_id_ls) кадра из данных с помощью необычной индексации для numpy arrary. Но я получил сообщение об ошибке при запуске code1. Я не знаю, почему форма data[n, :, valid_frame_id_ls, :, :] не равна форме new_data[n, :, :len(valid_frame_id_ls), :, :] .Кто-нибудь может помочь мне решить эту ошибку. Справка…

Я изменяю свой код и пишу в блоке code2. Я не получил никакого сообщения об ошибке при запуске code2. Я не знаю, почему код 2 правильный.

код1:

 
    data = np.random.random((2, 3, 50, 25, 1))
    N, C, T, V, M = data.shape
    new_data = np.zeros((N, C, T, V, M))
    valid_frame_id_ls = [2, 3, 4, 5, 6]
    for n in range(N):
        new_data[n, :, :len(valid_frame_id_ls), :, :] = data[n, :, valid_frame_id_ls, :, :]
 
 # code1 error message:
    new_data[n, :, :len(valid_frame_id_ls), :, :] = data[n, :, valid_frame_id_ls, :, :]
ValueError: could not broadcast input array from shape (5,3,25,1) into shape (3,5,25,1)
 

код2:

     data = np.random.random((2, 3, 50, 25, 1))
    N, C, T, V, M = data.shape
    new_data = np.zeros((N, C, T, V, M))
    valid_frame_id_ls = [2, 3, 4, 5, 11]
    for n in range(N):
        new_data[n][:, :len(valid_frame_id_ls), :, :] = data[n][ :, valid_frame_id_ls, :, :]
 

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

1. RHS-это сочетание basic и advanced индексации, документированная проблема. Ваш код2-это правильный способ обойти это.

Ответ №1:

https://numpy.org/doc/stable/reference/arrays.indexing.html#combining-advanced-and-basic-indexing

Как описано в этом разделе документов, размещение среза в середине «расширенной» индексации приводит к неожиданной перестановке измерений. Ваш размер 5 был помещен первым, а остальные размеры-после.

Это тоже время от времени всплывало в связи с ЭТИМ. Со скаляром n этого действительно не должно происходить, но, по-видимому, проблема возникает глубоко в индексации и ее нелегко исправить.

 data[n][ :, valid_frame_id_ls, :, :]
 

разбивает индексацию, поэтому первое»: «больше не находится посередине.

Другое исправление заключается в замене среза эквивалентным массивом. Теперь обе стороны будут иметь одинаковые размеры.

 new_data[n, :, np.arange(len(valid_frame_id_ls)), :, :] = data[n, :, valid_frame_id_ls, :, :]
 

Хотя в этом случае я не думаю, что вам N вообще нужно повторять:

 new_data[:,:,:len(valid_frame_id_ls),:,:] = data[:,:, valid_frame_id_ls, :,:]
 

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

1. спасибо за ваше объяснение, я понял. И документы так полезны.