繁体   English   中英

IndexError:创建二维数组时列表索引超出范围

[英]IndexError: list index out of range when creating 2D array

我试图获得一个大小为 235x20 的二维数组,以便对于 235 个 ROI 中的每一个,我根据存储在find_bootstrap_indices中的索引提取 20 个元素并将它们保存在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]

您需要在分配给它之前创建 new[roi][] ,即:

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]

这将创建元素列表并操作值

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]

另一种方法是 append 值。

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)

我认为你需要这样做:

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.

其他答案已经涵盖了如何修复错误,但不要提到有更简单的方法来完成整个事情。

概括地说,我可以想到人们使用 Numpy 的几个不同原因:

  1. Numpy arrays can be faster than Python lists, if you have lots of data per array, don't need to convert back and forth between Numpy arrays and python lists and you use Numpy operations which implicitly operate on the whole array, instead of looping over显式的单个元素
  2. 使用 Numpy arrays 的代码可以更简洁,因为你经常可以例如。 用单个 Numpy 操作替换多个嵌套循环
  3. 您只想使用 Numpy 中已有的一些功能

您错过了第 1 点和第 2 点; 您正在使用 Numpy,但您没有充分利用它,因此您的代码没有尽可能快速和简洁。

首先,一些非 Numpy 的建议:

  • 除非您使用range()的三参数形式,否则您可以省略开头 position 如果它是 0 - 即。 range(N)range(0, N) ) 做同样的事情
  • 如果您正在迭代列表/数组的所有索引,并且您仅将它们用于直接索引所述数组(即不用于例如计算),您应该直接迭代这些值 - 即。 而不是for i in range(len(items)): item = items[i] ,你应该for item in items:做。 如果还需要索引,可以说for i, item in enumerate(items):
  • 在您的内部循环中,您只是一个接一个地复制项目 - 如果您不需要单独对项目执行任何操作,只需在一个 go 中执行:(我将缩短extract_bootstrap_timepointebt
    • 如果类型没问题,并且您不需要副本,只需像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 建议:

  • np.take(arr, indices)精美的索引; 具体来说,如果arr是 Numpy 数组并且indices是 Python 列表,则相当于arr[indices]
  • 正常的 Numpy 索引返回相同共享数据的新视图,但是当您使用花式索引时,您会获得数据的副本(因此即使您需要副本,在这种情况下也无需显式复制)

由于您只是对rsfMRI_timeseries_2d中的每一行执行相同的操作,并且np.take调用也可以通过索引替换,因此整个循环可以替换为:

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

Although, since you're using Numpy, you'll probably want to be working with Numpy arrays instead of nested Python lists - If so, the whole thing becomes just:

new = rsfMRI_timeseries_2d[:,find_bootstrap_indices]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM