【问题标题】:Create array from slices of numpy arrays contained in a list object从列表对象中包含的 numpy 数组切片创建数组
【发布时间】:2019-12-17 21:16:27
【问题描述】:

我有一个形状为(7761940, 16) 的熊猫数据框。我使用 np.array_split 将其转换为 7762 个 numpy 数组的列表,每个数组的形状为 (1000, 16) 。

现在我需要从每个数组中取出前 50 个元素的切片,并从中创建一个形状为 (388100, 16) 的新数组。数字 388100 来自 7762 个数组乘以 50 个元素。

我知道这是一种切片和索引,但我无法管理它。

【问题讨论】:

  • 列表理解:np.vstack([arr[:50,:] for arr in split_list]) 应该可以工作。或者将原始数组重新整形为 (7762, 1000,16),将切片使用[:,:50,:] 重新整形,然后使用 (-1,16) 重新整形为 2d。
  • 并非所有数组都有 1000 行。填充可能会更好。

标签: python arrays list numpy split


【解决方案1】:

在得到朋友cmet和一些调查的帮助后,我想出了一个解决方案:

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

【讨论】:

  • 您可以直接遍历my_data,因此将最后三行简化为列表理解。这不会为您创建数组,效率也不高。
【解决方案2】:

如果拆分数组,则会浪费内存。如果您填充数组以进行良好的整形,则会浪费内存。这不是一个大问题,但可以避免。一种方法是使用神秘的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])

一个更健康的方法是填充和重塑原件。

【讨论】:

  • 非常感谢您的回复,节省内存在此过程中具有至关重要的影响。非常感谢@Mad Physicist。
  • @saad。您应该测试我的答案,因为我在编写它时无法访问桌面。如果可行,请随意选择它。
【解决方案3】:

你可以这样做:

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

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

    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 看看。

【讨论】:

  • 感谢 Rick M. 的回复,但这是我在应用第二次拆分时得到的: in ----> 1 data_second_split = data_first_split[: , :50, :] TypeError: list indices must be integers or slices, not tuple
  • 尝试做 np.array(np.array_split(data, 7762)) 代替。
  • 如果要在拆分后立即重新组装,请不要拆分。
  • 拆分不返回数组
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2020-11-29
  • 2011-01-07
  • 1970-01-01
  • 2021-08-31
相关资源
最近更新 更多