在 numpy 数组中加载大型异构数据集的有效方法?
Efficient way to load big heterogeneous dataset in a numpy array?
我必须将数据集加载到具有 p
个实例的大数组中,其中每个实例有 2 个维度 (n_i, m)
。第一维的长度n_i
是可变的
我的第一个方法是在第一个维度上将所有实例填充到 max_len
,初始化一个大小为 (p, max_len, m)
的数组,然后将每个实例广播到大数组中,如下所示 big_array[i*max_len:i*max_len+max_len] = padded_i_instance
.这很快并且运行良好,问题是我只有 8Gb 的 RAM,当我尝试加载整个数据集时我得到 (interrupted by signal 9: SIGKILL) error
。它也感觉非常浪费,因为最短的实例几乎比 max_len
短 10 倍,所以有些实例是 90% 的填充。
我的第二种方法是使用 np.vstack
然后迭代构建 big_array
。像这样:
big_array = np.zeros([1,l])
for i in range(1,n):
big_array = np.vstack([big_array, np.full([i,l], i)])
这感觉不那么“浪费”,但实际上仅执行 10000 个实例需要 100 倍的时间,用于 100k+ 是不可行的。
所以我想知道是否有一种方法既比方法 1 的内存效率更高,又比方法 2 的计算效率更高。我读到了 np.append
和 np.insert
,但它们似乎是np.vstack
的其他版本,所以我认为这将花费大致相同的时间。
缓慢的重复vstack:
In [200]: n=5; l=2
...: big_array = np.zeros([1,l])
...: for i in range(1,n):
...: big_array = np.vstack([big_array, np.full([i,l], i)])
...:
In [201]: big_array
Out[201]:
array([[0., 0.],
[1., 1.],
[2., 2.],
[2., 2.],
[3., 3.],
[3., 3.],
[3., 3.],
[4., 4.],
[4., 4.],
[4., 4.],
[4., 4.]])
列表追加速度更快:
In [202]: alist = []
In [203]: for i in range(1,n):
...: alist.append(np.full([i,l], i))
...:
...:
In [204]: alist
Out[204]:
[array([[1, 1]]),
array([[2, 2],
[2, 2]]),
array([[3, 3],
[3, 3],
[3, 3]]),
array([[4, 4],
[4, 4],
[4, 4],
[4, 4]])]
In [205]: np.vstack(alist)
Out[205]:
array([[1, 1],
[2, 2],
[2, 2],
[3, 3],
[3, 3],
[3, 3],
[4, 4],
[4, 4],
[4, 4],
[4, 4]])
填充预分配数组:
In [210]: arr = np.zeros((10,2),int)
...: cnt=0
...: for i in range(0,n):
...: arr[cnt:cnt+i,:] = np.full([i,l],i)
...: cnt += i
...:
In [211]: arr
Out[211]:
array([[1, 1],
[2, 2],
[2, 2],
[3, 3],
[3, 3],
[3, 3],
[4, 4],
[4, 4],
[4, 4],
[4, 4]])
我必须将数据集加载到具有 p
个实例的大数组中,其中每个实例有 2 个维度 (n_i, m)
。第一维的长度n_i
是可变的
我的第一个方法是在第一个维度上将所有实例填充到 max_len
,初始化一个大小为 (p, max_len, m)
的数组,然后将每个实例广播到大数组中,如下所示 big_array[i*max_len:i*max_len+max_len] = padded_i_instance
.这很快并且运行良好,问题是我只有 8Gb 的 RAM,当我尝试加载整个数据集时我得到 (interrupted by signal 9: SIGKILL) error
。它也感觉非常浪费,因为最短的实例几乎比 max_len
短 10 倍,所以有些实例是 90% 的填充。
我的第二种方法是使用 np.vstack
然后迭代构建 big_array
。像这样:
big_array = np.zeros([1,l])
for i in range(1,n):
big_array = np.vstack([big_array, np.full([i,l], i)])
这感觉不那么“浪费”,但实际上仅执行 10000 个实例需要 100 倍的时间,用于 100k+ 是不可行的。
所以我想知道是否有一种方法既比方法 1 的内存效率更高,又比方法 2 的计算效率更高。我读到了 np.append
和 np.insert
,但它们似乎是np.vstack
的其他版本,所以我认为这将花费大致相同的时间。
缓慢的重复vstack:
In [200]: n=5; l=2
...: big_array = np.zeros([1,l])
...: for i in range(1,n):
...: big_array = np.vstack([big_array, np.full([i,l], i)])
...:
In [201]: big_array
Out[201]:
array([[0., 0.],
[1., 1.],
[2., 2.],
[2., 2.],
[3., 3.],
[3., 3.],
[3., 3.],
[4., 4.],
[4., 4.],
[4., 4.],
[4., 4.]])
列表追加速度更快:
In [202]: alist = []
In [203]: for i in range(1,n):
...: alist.append(np.full([i,l], i))
...:
...:
In [204]: alist
Out[204]:
[array([[1, 1]]),
array([[2, 2],
[2, 2]]),
array([[3, 3],
[3, 3],
[3, 3]]),
array([[4, 4],
[4, 4],
[4, 4],
[4, 4]])]
In [205]: np.vstack(alist)
Out[205]:
array([[1, 1],
[2, 2],
[2, 2],
[3, 3],
[3, 3],
[3, 3],
[4, 4],
[4, 4],
[4, 4],
[4, 4]])
填充预分配数组:
In [210]: arr = np.zeros((10,2),int)
...: cnt=0
...: for i in range(0,n):
...: arr[cnt:cnt+i,:] = np.full([i,l],i)
...: cnt += i
...:
In [211]: arr
Out[211]:
array([[1, 1],
[2, 2],
[2, 2],
[3, 3],
[3, 3],
[3, 3],
[4, 4],
[4, 4],
[4, 4],
[4, 4]])