我有一个形状为(7761940, 16)
的熊猫数据框。我使用np.array_split
将其转换为 7762 个 numpy 数组的列表,每个数组的形状(1000, 16)
。
现在我需要从每个数组中获取前 50 个元素的一部分,并从中创建一个新的形状(388100, 16)
数组。数字 388100 来自 7762 个数组乘以 50 个元素。
我知道这是一种切片和索引,但我无法管理它。
如果拆分数组,则会浪费内存。如果你填充数组以允许一个漂亮的重塑,你会浪费内存。这不是一个大问题,但可以避免。一种方法是使用晦涩的np.lib.stride_tricks.as_strided
功能。这个函数很危险,我们会用它破坏一些规则,但只要你只想要一个块的前 50 个元素,最后一个块超过 50 个元素,一切都会好起来的:
x = ... # your data as a numpy array
chunks = int(np.ceil(x.shape[0] / 1000))
view = np.lib.stride_tricks.as_strided(x, shape=(chunks, 1000, x.shape[-1]), strides=(np.max(*x.strides) * 1000, *x.strides))
这将创建形状的视图(7762, 1000, 16)
到原始内存中,而无需复制。由于您的原始数组没有 1000 行的倍数,因此最后一个平面将有一些不属于您的内存。只要您不尝试访问它,它就不会伤害您。
现在访问每个平面的前 50 个元素是微不足道的:
data = view[:, :50, :]
您可以解开第一个维度以获得最终结果:
data.reshape(-1, x.shape[-1])
更健康的方法是填充和重塑原件。
在从朋友的评论和一些调查中受益后,我想出了一个解决方案:
my_data = np.array_split(dataframe, 7762) #split dataframe to a list of 7762 ndarray
#each of 1000x16 dimension
my_list = [] #define new list object
for i in range(0,7762): #loop to iterate over the 7762 ndarrays
my_list.append(my_data[i][0:50, :]) #append first 50 rows from each adarray into my_list
你可以做这样的事情:
-
将大小(7762000 x 16(的数据拆分为(7762 x 1000 x 16(
data_first_split = np.array_split(data, 7762)
-
将数据切片为 7762 x 50 x 16,以获得前 50 个元素data_first_split
data_second_split = data_first_split[:, :50, :]
-
重塑形状以获得 388100 x 16
data_final = np.reshape(data_second_split, (7762 * 50, 16))
如@hpaulj所述,您也可以使用 NP.vstack。IMO 你也应该给 numpy.strides 看看。