转换为numpy数组崩溃RAM

时间:2015-08-25 18:22:02

标签: python arrays numpy

我有一个numpy数组列表。该列表有200000个元素,每个数组的大小为3504.这在我的RAM中工作正常。 类型(x)的

(Pdb) type(x)
<type 'list'>
(Pdb) len(x)
200001
(Pdb) type(x[1])
<type 'numpy.ndarray'>
(Pdb) x[1].shape
(3504L,)

问题是,现在我将列表转换为numpy数组,它超过了RAM 100%的使用率并冻结/崩溃了我的电脑。 我转换的意图是执行一些功能扩展和PCA。

修改 我想将每个样本转换为连接早期1000个样本加上其自身的数组。

def take_previous_data(X_train,y):
    temp_train_data=X_train[1000:]
    temp_labels=y[1000:] 
    final_train_set=[]
    for index,row in enumerate(temp_train_data):
        actual_index=index+1000
        data=X_train[actual_index-1000:actual_index+1].ravel()
        __,cd_i=pywt.dwt(data,'haar')
        final_train_set.append(cd_i)
    return final_train_set,y


x,y=take_previous_data(X_train,y)

1 个答案:

答案 0 :(得分:2)

你可以尝试重写take_previous_data作为generator function懒惰地产生最终数组的行,然后使用np.fromiter,正如Eli建议的那样:

from itertools import chain

def take_previous_data(X_train,y):
    temp_train_data=X_train[1000:]
    temp_labels=y[1000:] 
    for index,row in enumerate(temp_train_data):
        actual_index=index+1000
        data=X_train[actual_index-1000:actual_index+1].ravel()
        __,cd_i=pywt.dwt(data,'haar')
        yield cd_i

gen = take_previous_data(X_train, y)

# I'm assuming that by "int" you meant "int64"
x = np.fromiter(chain.from_iterable(gen), np.int64)

# fromiter gives a 1D output, so we reshape it into a (200001, 3504) array
x.shape = 200001, -1

另一个选择是预先分配输出数组并在进行时填充行:

def take_previous_data(X_train, y):
    temp_train_data=X_train[1000:]
    temp_labels=y[1000:] 
    out = np.empty((200001, 3504), np.int64)
    for index,row in enumerate(temp_train_data):
        actual_index=index+1000
        data=X_train[actual_index-1000:actual_index+1].ravel()
        __,cd_i=pywt.dwt(data,'haar')
        out[index] = cd_i
    return out

从我们的聊天对话中,似乎根本问题是您实际上无法将输出数组本身放入内存中。在这种情况下,您可以调整第二个解决方案以使用np.memmap将输出数组写入磁盘:

def take_previous_data(X_train, y):
    temp_train_data=X_train[1000:]
    temp_labels=y[1000:] 
    out = np.memmap('my_array.mmap', 'w+', shape=(200001, 3504), dtype=np.int64)
    for index,row in enumerate(temp_train_data):
        actual_index=index+1000
        data=X_train[actual_index-1000:actual_index+1].ravel()
        __,cd_i=pywt.dwt(data,'haar')
        out[index] = cd_i
    return out

另一个明显的解决方案是减少阵列的位深度。我假设int你的意思是int64(numpy中的默认整数类型)。如果您可以切换到较低的位深度(例如int32int16或甚至int8),则可以大幅降低内存需求。