IndexError: список индексов вне диапазона при создании 2D-массива - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь получить двумерный массив размером 235x20, чтобы для каждого из 235 ROI я извлекал 20 элементов на основе индексов, хранящихся в find_bootstrap_indices, и сохранял их в extract_bootstrap_timepoint. Теперь я хочу сохранить значения каждого ROI и соответствующих ему 20 элементов в массиве. Я попытался сделать это, имея эту строку new[roi][timepoint] = extract_bootstrap[timepoint], но у меня есть индекс вне ошибки диапазона. Любая помощь в том, как решить эту проблему, будет очень цениться. Спасибо.

new = []
for roi in range(0, rsfMRI_timeseries_2d.shape[0]):
        extract_bootstrap_timepoint = np.take(rsfMRI_timeseries_2d[roi, :], find_bootstrap_indices)
        for timepoint in range(0, len(extract_bootstrap_timepoint)):
            new[roi][timepoint] = extract_bootstrap_timepoint[timepoint]

Ответы [ 4 ]

0 голосов
/ 27 апреля 2020

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

В целом, я могу придумать несколько разных причин, почему люди используют Numpy:

  1. Numpy массивы могут быть быстрее, чем списки Python, если у вас много данных на массив, вам не нужно конвертировать туда и обратно между Numpy массивами и python перечисляет, и вы используете Numpy операции, которые неявно работают со всем массивом, вместо того, чтобы явно зацикливаться на отдельных элементах
  2. Код с использованием Numpy массивов может быть более кратким, поскольку вы можете, например, часто. заменить несколько вложенных циклов одной Numpy операцией
  3. Вы просто хотите использовать некоторые функции, которые уже доступны в Numpy

Вам не хватает точек 1 и 2; Вы используете Numpy, но не пользуетесь им в полной мере, поэтому ваш код не такой быстрый и лаконичный, как мог бы.

Во-первых, несколько не Numpy слов совета:

  • Если вы не используете форму с тремя аргументами range(), вы можете опустить стартовую позицию, если она 0 - ie. range(N) делает то же самое, что и range(0, N)
  • Если вы перебираете все индексы списка / массива и используете их только для прямой индексации указанного массива (ie. Не например, для вычислений), вы должны просто перебрать значения вместо - ie. вместо for i in range(len(items)): item = items[i] вы должны сделать for item in items:. Если вам также нужен указатель, вы можете сказать for i, item in enumerate(items):
  • Во внутреннем l oop вы просто копируете элементы по одному - если вам не нужно ничего делать с элементы по отдельности, просто сделайте это за один go: (я буду сокращать extract_bootstrap_timepoint до ebt)
    • Если тип в порядке, и вам не нужна копия, просто назначьте ее например new[roi] = ebt
    • Если это массив (как здесь) и вам нужен список, просто сначала преобразуйте его с помощью new[roi] = list(ebt) или new[roi] = ebt.tolist() (последний работает только с массивами)
    • Если это уже список, и вам нужна копия, просто сделайте копию, например new[roi] = ebt.copy() или new[roi] = ebt[:] (последняя не работает с массивами)
    • Если у вас уже есть более длинный список, и вы просто Если вы хотите перезаписать столько элементов, сколько у вас есть, вы можете использовать назначение фрагментов, например new[roi][:len(ebt)] = ebt

Итак, применяя этот совет, ваш код упрощается до:

new = []
for row in rsfMRI_timeseries_2d:
        new.append(np.take(row, find_bootstrap_indices).tolist())

Теперь перейдем к более Numpy -specifi c совету:

  • np.take(arr, indices) делает интересную индексацию; В спецификациях c, если arr является массивом Numpy и indices является списком Python, это эквивалентно arr[indices]
  • Normal Numpy индексирование возвращает новое представление в те же общие данные, но когда вы используете необычную индексацию, вы получаете копию данных (так что даже если вам нужна копия, вам не нужно явно копировать в этом случае)

Поскольку вы просто Если вы сделаете то же самое для каждой строки в rsfMRI_timeseries_2d, и вызов np.take также можно будет заменить индексированием, то весь l oop можно заменить на:

new = rsfMRI_timeseries_2d[:,find_bootstrap_indices].tolist()

Хотя, поскольку вы вы используете Numpy, вы, вероятно, захотите работать с массивами Numpy вместо вложенных Python списков - если это так, то все становится просто:

new = rsfMRI_timeseries_2d[:,find_bootstrap_indices]
0 голосов
/ 26 апреля 2020

Создает список элементов и манипулирует значением

new = [0]*rsfMRI_timeseries_2d.shape[0]
for roi in range(0, rsfMRI_timeseries_2d.shape[0]):
    xtract_bootstrap_timepoint = np.take(rsfMRI_timeseries_2d[roi, :], find_bootstrap_indices)
    new[roi]=[0]*len(extract_bootstrap_timepoint)
    for timepoint in range(0, len(extract_bootstrap_timepoint)):
        new[roi][timepoint] = extract_bootstrap_timepoint[timepoint]

Еще один метод - добавление значений.

new = []
for roi in range(0, rsfMRI_timeseries_2d.shape[0]):
    xtract_bootstrap_timepoint = np.take(rsfMRI_timeseries_2d[roi, :], find_bootstrap_indices)
    l=list()
    for timepoint in range(0, len(extract_bootstrap_timepoint)):
        l.append(extract_bootstrap_timepoint[timepoint])
    new.append(l)
0 голосов
/ 26 апреля 2020

Я думаю, вам нужно сделать что-то вроде этого:

new = []
for roi in range(0, rsfMRI_timeseries_2d.shape[0]):
    extract_bootstrap_timepoint = np.take(rsfMRI_timeseries_2d[roi, :], find_bootstrap_indices)
    new[roi] = extract_bootstrap_timepoint[:] # Copy data.
0 голосов
/ 26 апреля 2020

Вам необходимо создать новый [roi] [], прежде чем назначить ему ie:

new = []
for roi in range(0, rsfMRI_timeseries_2d.shape[0]):
        extract_bootstrap_timepoint = np.take(rsfMRI_timeseries_2d[roi, :], find_bootstrap_indices)
        new[roi] = []
        for timepoint in range(0, len(extract_bootstrap_timepoint)):
            new[roi][timepoint] = extract_bootstrap_timepoint[timepoint]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...