首页 > 解决方案 > 当数组未初始化时,哪种是创建数组堆栈的最佳方式?

问题描述

假设我有一个数组M,我想去掉一些行块。事实上,我想做一些类似于以下代码实现的事情(在哪里bot_indicestop_indices并且M在代码的其他地方得到了很好的定义):

for i_bot, i_top in zip(bot_indices, top_indices):
        M_new = np.vstack((M_new, M[i_bot:i_top]))

问题是,在for语句的第一次迭代中,M_new没有定义,所以我会得到一个NameError. 为了克服这个问题,我想添加一个try/except语句:

for i_bot, i_top in zip(bot_indices, top_indices):
        try:
            M_new = np.vstack((M_new, M[i_bot:i_top]))
        except NameError:
            M_new = M[i_bot:i_top]

现在,问题是,如果此代码块嵌入在fororwhile语句中,并且M_new在第二次访问所示块时已经存在,它将最终包含每次访问块时生成的所有数组的串联。换句话说,我需要M_new在所示块的末尾“初始化”(可能带有del(M_new)?)。

解决这个问题的最佳方式是哪种(就可读性、运行时间和代码长度而言)?

标签: pythonarraysnumpy

解决方案


您不想过滤M并将结果附加到新数组,而是希望一步完成过滤:

filter_indices = np.array([0, 1, 2, 10, 11, 12, 13])
M[filter_indices]

您可以使用此方法从索引创建一个通用范围的索引,并M在一个操作中进行过滤:

import numpy as np

def create_ranges(a):
    a = np.asarray(a)
    l = a[:,1] - a[:,0]
    clens = l.cumsum()
    ids = np.ones(clens[-1],dtype=int)
    ids[0] = a[0,0]
    ids[clens[:-1]] = a[1:,0] - a[:-1,1]+1
    out = ids.cumsum()
    return out

M = np.random.rand(1024, 1024)
bot_indices = [10, 20, 60]
top_indices = [15, 30, 100]

limits = np.asarray([bot_indices, top_indices]).T

filter_indices = create_ranges(limits)
filter_indices
# array([10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 25, ...])
M[filter_indices]

推荐阅读