Python训练数组太大了

时间:2014-08-22 19:42:52

标签: python arrays

因此,我需要使用超过3000万个对象作为我的训练数据。我的问题很简单:当我通过迭代append进程创建训练数组时,在某个阈值处,列表变得太大而python被杀死。有什么方法可以解决这个问题?我一直在试图解决这个问题几个小时,并且不断出现!

创建训练数组的代码示例

training_array = []
for ...:
    data = #load data from somewhere
    data_array = [x for x in data] #some large array, 2-3 million objects  
    for item in data_array:
        training_array.append(item.a + item.b)

过了一会儿,"killed"被打印到consol和python退出。我怎么能避免这个?

更具体的问题措辞:

我正在尝试训练一个非常大的数组,但在制作数组时,python会被杀死。这种训练算法无法在数据块上进行训练,但需要一个完整的阵列,这限制了我知道如何超越这个问题的唯一方法。有没有另一种方法来创建这个数组而不使用我的所有RAM(如果这是实际问题)?

2 个答案:

答案 0 :(得分:3)

  • data是一个Python列表吗?如果是,那么

    data_array = [x for x in data]
    

    是不必要的,因为它与说

    相同
    data_array = list(data)
    

    制作data的副本。这使内存量增加了一倍 需要,但目前尚不清楚它的用途是什么。

    另请注意,del data允许Python在不再需要时回收data使用的内存。

  • 另一方面,也许data是一个迭代器。如果是这样的话, 那么你可以通过避免创建Python来节省内存 列表,data_array。特别是,您不需要data_array 定义training_array。你可以替换

    data_array = [x for x in data] #some large array, 2-3 million objects  
    for item in data_array:
        training_array.append(item.a + item.b)
    

    使用list comprehension

    training_array = [x.a + x.b for x in data]
    
  • 如果您正在使用NumPy并且最终希望training_arary成为 NumPy数组,然后你可以通过避免更多的内存来节省 创建中间Python列表training_array。您 直接从training_data定义NumPy数组data

    training_array = np.fromiter((x.a + x.b for x in data),
                                 dtype=...)
    

    请注意,(x.a + x.b for x in data)generator expression,因此我们在此处使用列表解析时避免了更大的内存量。

    如果您知道data的长度,请在呼叫中添加count=... np.fromiter会加速其表现,因为它会允许 NumPy为最终阵列预先分配适量的内存。

    您还必须指定正确的dtype。如果值在 training_array是浮点数,你可以节省内存(代价是 精度)通过指定具有较小项目大小的dtype。对于 例如,dtype='float32'使用4将每个float存储在数组中 字节(即32位)。通常NumPy使用float64,它是8字节的浮点数。所以你可以 使用较小的数组创建一个较小的数组(从而节省内存) D型。

  • 如果您的内存不足,那么您可以使用 np.memmap创建基于文件的数组而不是基于内存的数组 阵列。同样的其他选项包括使用h5pypytables创建一个hdf5文件。

答案 1 :(得分:0)

您可以做一些事情:

  1. 以块的形式处理您的数据 - 这将使您在任何给定时间都不会拥有怪物数组,并且应该有助于降低开销。

  2. 从生成器生成数据 - 生成器被“懒惰地”评估,这意味着它们不会同时存在。每个元素都是在你召唤它时创建的,而不是更快,让你不再拥有怪物阵列。如果你不熟悉它们,发电机可能有点棘手,但是周围有很多资源。

  3. 针对您的具体问题,请尝试使用此生成器:

    def train_gen(data):
        data_gen = (x for x in data)  #The () here are important as it makes data_gen a generator as well, as opposed to a list
        for item in data_gen:
            yield item.a + item.b
    
    
    data = #load data from somewhere
    training_array = train_gen(data)
    
    for item in training_array:
        #Iterates through training_array, producing one value, then discarding it such that only one item in training_array is in memory at a time