numpy vstack 空初始化

Posted

技术标签:

【中文标题】numpy vstack 空初始化【英文标题】:numpy vstack empty initialization 【发布时间】:2015-02-02 21:00:55 【问题描述】:

我有 vstacked 图像数据,现在我希望将其拆分为训练和测试集。 但是如何初始化一个空的 numpy 数组以便开始 vstacking?

我的简化代码如下所示:

#k-fold the data
kf = cross_validation.KFold(n, n_folds=2)
fold = 0
for train_ind, test_ind in kf:
    #Get the persons of k-fold
    train_pers = unique[train_ind]
    test_pers = unique[test_ind]
    
    #Set train+test stack to empty
    self.train_stack = type(self.pca_data[0])
    self.test_stack = type(self.pca_data[0])
            
    #For all test data
    for data in range(len(self.pca_data)):
        print(self.pca_pers[data])
        if self.pca_pers[data] in train_pers:
            #Add to train stack
            self.train_stack = np.vstack((self.train_stack, self.pca_data[data]))
            
        elif self.pca_pers[data] in test_pers:
            #Add to test stack
            self.test_stack = np.vstack((self.test_stack, self.pca_data[data]))
        else:
            #Something wrong
            print(data)
            sys.exit("Strange strange data")
            
    fold += 1

这里的导入代码是:

#Set train+test stack to empty
self.train_stack = type(self.pca_data)
self.test_stack = type(self.pca_data)

#Add to train stack
self.train_stack = np.vstack((self.train_stack, self.pca_data[fold][data]))

self.pca_data 包含所有图像数据,这些数据必须分布在 self.train_stackself.test_stack 上。我尝试了 type() 函数,但这似乎是错误的。我也尝试了 self.train_stack = [],但这会引发错误“ValueError:数组维度必须一致,除了 d_0”。如果我要使用 numpy.zeros,那么第一个堆栈是 0,我希望它在 vstacking 之前完全为空。

问题

初始化空 numpy 数组的正确方法是什么? (输入“numpy.ndarray”)

附言注意self.train_stack是循环的,所以if语句,for if变量不存在,第二次进入循环时不会重置变量。

变量

self.pca_data: Shape(978, 20) Type(type 'numpy.ndarray') self.pca_pers: Shape(978, 1) Type(type 'numpy.ndarray') self.test_stack 和 self.train_stack 应该用于例如Shape(489, 20) 和 Shape(489, 20) 类似 self.pca_data 您可以忽略的其他变量

【问题讨论】:

请告诉我们哪些变量是标量,哪些是数组,哪些是数组的形状。 【参考方案1】:

避免在循环中调用np.vstack。每次你这样做, 分配了一个新数组,并且 原始数组和新行中的所有数据复制到新数组中。 所有这些复制都使这样的解决方案变得比必要的慢。

如果我们可以假设self.pca_data 的每一行都属于self.train_stackself.test_stack,那么您可以替换整个for-loop

for data in range(len(self.pca_data)):
    ...

调用np.in1d 创建一个布尔掩码,然后 通过使用掩码索引self.pca_data 来定义self.train_stackself.test_stack

for fold, (train_ind, test_ind) in enumerate(kf):
    train_pers = unique[train_ind]
    mask = np.in1d(self.pca_pers[:,0], train_pers)
    self.train_stack = self.pca_data[mask]
    self.test_stack = self.pca_data[~mask]

例如,np.in1d 创建一个布尔数组 True 当元素 在第一个类数组中是在第二个类数组中:

In [544]: np.in1d(range(5), [1,2,4])
Out[544]: array([False,  True,  True, False,  True], dtype=bool)

布尔索引可以用来选择这样的行:

In [545]: mask = np.in1d(range(5), [1,2,4])

In [546]: x = np.arange(10).reshape(5,-1)

In [547]: x
Out[547]: 
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])

In [548]: x[mask]
Out[548]: 
array([[2, 3],
       [4, 5],
       [8, 9]])

【讨论】:

谢谢!这是比我尝试做的更有效的方法。我的代码的其他部分我没有拥有所有数据的奢侈,但我得到了一张一张图片。你知道在这种情况下如何为 np.vstack() 初始化一个变量吗? 你可以使用self.train_stack = np.empty((0, self.pca_data.shape[1]), dtype=self.pca_data.dtype),虽然它可能会很慢。如果您有内存,将行附加到列表中会更快,然后只需调用np.array once (循环完成后)将行列表转换为二维数组。 感谢我一直在寻找!我知道有一些简单的解决方案。我把这个建议牢记在心:)

以上是关于numpy vstack 空初始化的主要内容,如果未能解决你的问题,请参考以下文章

创建一个基于空的numpy数组并附加现有数组

numpy数组的堆叠:numpy.stack, numpy.hstack, numpy.vstack

在 numba 中使用 numpy.vstack

Numpy总结第三节:Numpy创建数组

numpy基础四

numpy中vstack以及hstack的使用详解