如何仅展平numpy数组的某些维度

Cur*_*ous 98 python numpy flatten

有没有一种快速的方法来"压平"或平整一些numpy数组中的第一个维度?

例如,给定一个numpy维度数组(50,100,25),结果尺寸将是(5000,25)

Ale*_*der 109

看看numpy.reshape.

>>> arr = numpy.zeros((50,100,25))
>>> arr.shape
# (50, 100, 25)

>>> new_arr = arr.reshape(5000,25)
>>> new_arr.shape   
# (5000, 25)

# One shape dimension can be -1. 
# In this case, the value is inferred from 
# the length of the array and remaining dimensions.
>>> another_arr = arr.reshape(-1, arr.shape[-1])
>>> another_arr.shape
# (5000, 25)
Run Code Online (Sandbox Code Playgroud)

  • 这样的解决方案对我来说似乎有点不优雅,因为它们需要一些冗余信息。我希望有一种方法可以做到这一点,只需要指定维度的子集,比如“arr.flatten(dimensions=(0, 1))”。 (10认同)
  • @אלמלךשרבבר有趣的是,火炬似乎以某种方式管理这个:https://pytorch.org/docs/stable/ generated/torch.flatten.html ;) (5认同)
  • @Denziloe 不能简单地“展平”ndarray 的任意维度,而不指定额外数据将折叠到哪个维度。以 2x2x3 ndarray 为例,展平最后一个维度可以产生 2x6 或 6x2,因此信息不是多余的。您可以使用 -1 指定尺寸:来自 [numpy.reshape](http://docs.scipy.org/doc/numpy/reference/ generated/numpy.reshape.html) 一个形状尺寸可以是 -1。在这种情况下,该值是根据数组的长度和剩余维度推断出来的。因此,将 2x2xN 重塑为 2Nx2 看起来像这样:`arr.reshape((-1,2))`。 (2认同)
  • @Denziloe实现这一点的方法可能类似于“arr.reshape(arr.shape[0] * arr.shape[1], arr.shape[2])” (2认同)

Pet*_*ter 74

对Alexander的答案略有概括 - np.reshape可以将-1作为参数,意思是"总数组大小除以所有其他列出的维度的乘积":

例如,除了最后一个维度之外的所有内容:

>>> arr = numpy.zeros((50,100,25))
>>> new_arr = arr.reshape(-1, arr.shape[-1])
>>> new_arr.shape
# (5000, 25)
Run Code Online (Sandbox Code Playgroud)


Kei*_*hWM 23

稍微概括一下Peter的答案 - 如果你想要超越三维数组,你可以指定原始数组形状的范围.

例如,除了最后两个维度之外的所有内容:

arr = numpy.zeros((3, 4, 5, 6))
new_arr = arr.reshape(-1, *arr.shape[-2:])
new_arr.shape
# (12, 5, 6)
Run Code Online (Sandbox Code Playgroud)

编辑:稍微概括一下我之前的答案 - 你当然也可以在重塑的开头指定一个范围:

arr = numpy.zeros((3, 4, 5, 6, 7, 8))
new_arr = arr.reshape(*arr.shape[:2], -1, *arr.shape[-2:])
new_arr.shape
# (3, 4, 30, 7, 8)
Run Code Online (Sandbox Code Playgroud)

  • 已经过去两年多了……我们需要再次稍微概括一下!;) (14认同)

She*_*man 17

numpy.vstack非常适合这种情况

import numpy as np
arr = np.ones((50,100,25))
np.vstack(arr).shape
> (5000, 25)
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用stack,vstackhstackoverreshape因为它reshape只是扫描数据并且似乎将其强制转换为所需的形状。例如,如果您要获取列平均值,这可能会出现问题。

这是我的意思的一个例子。假设我们有以下数组

>>> arr.shape
(2, 3, 4)
>>> arr 
array([[[1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4]],

       [[7, 7, 7, 7],
        [7, 7, 7, 7],
        [7, 7, 7, 7]]])

Run Code Online (Sandbox Code Playgroud)

我们应用这两种方法来获得形状为 (3,8) 的数组

>>> arr.reshape((3,8)).shape
(3, 8)
>>> np.hstack(arr).shape 
(3, 8)
Run Code Online (Sandbox Code Playgroud)

然而,如果我们看看它们在每种情况下是如何被重塑的,那么hstack我们就可以得到列的总和,我们也可以从原始数组中计算出列的总和。通过重塑,这是不可能的。

>>> arr.reshape((3,8))
array([[1, 2, 3, 4, 1, 2, 3, 4],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [7, 7, 7, 7, 7, 7, 7, 7]])
>>> np.hstack(arr)
array([[1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7]])
Run Code Online (Sandbox Code Playgroud)


kma*_*o23 6

另一种方法是使用numpy.resize()如下所示:

In [37]: shp = (50,100,25)
In [38]: arr = np.random.random_sample(shp)
In [45]: resized_arr = np.resize(arr, (np.prod(shp[:2]), shp[-1]))
In [46]: resized_arr.shape
Out[46]: (5000, 25)

# sanity check with other solutions
In [47]: resized = np.reshape(arr, (-1, shp[-1]))
In [48]: np.allclose(resized_arr, resized)
Out[48]: True
Run Code Online (Sandbox Code Playgroud)