从列表对象中包含的 numpy 数组切片创建数组



我有一个形状为(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

你可以做这样的事情:

  1. 将大小(7762000 x 16(的数据拆分为(7762 x 1000 x 16(

    data_first_split = np.array_split(data, 7762)
    
  2. 将数据切片为 7762 x 50 x 16,以获得前 50 个元素data_first_split

    data_second_split = data_first_split[:, :50, :]
    
  3. 重塑形状以获得 388100 x 16

    data_final = np.reshape(data_second_split, (7762 * 50, 16))
    

如@hpaulj所述,您也可以使用 NP.vstack。IMO 你也应该给 numpy.strides 看看。

最新更新