-1在numpy重塑中是什么意思?

使用.reshape(-1)可以将2D数组重新塑造为1D数组。 例如:< / p >
>>> a = numpy.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> a.reshape(-1)
array([[1, 2, 3, 4, 5, 6, 7, 8]])
通常,array[-1]表示最后一个元素。 这里-1是什么意思?< / p >
574604 次浏览

根据the documentation:

Newshape: int或int的元组

新形状应该与原始形状兼容。如果一个 整数,则结果将是该长度的一维数组。一个形状 维度可以是-1。在本例中,该值是从 数组的长度和剩余维度。

.数组的长度和剩余维度
numpy.reshape(a,newshape,order{})

查看下面的链接获取更多信息。 # EYZ0 < / p >

对于你提到的下面的例子,输出将结果向量解释为单行。(-1)表示行数为1。 如果< / p >

a = numpy.matrix([[1, 2, 3, 4], [5, 6, 7, 8]])
b = numpy.reshape(a, -1)

输出:

matrix([[1, 2, 3, 4, 5, 6, 7, 8]])

这可以用另一个例子来更准确地解释:

b = np.arange(10).reshape((-1,1))

输出:(1维柱状阵列)

array([[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])

b = np.arange(10).reshape((1,-1))

输出:(是一个1维行数组)

array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

-1代表“未知维度”;这可以从另一个维度推断出来。 在这种情况下,如果你像这样设置你的矩阵:

a = numpy.matrix([[1, 2, 3, 4], [5, 6, 7, 8]])

像这样修改你的矩阵:

b = numpy.reshape(a, -1)

它将调用一些对矩阵a的默认操作,这将返回一个1-d的numpy数组/矩阵。

然而,我不认为使用这样的代码是一个好主意。为什么不试试呢:

b = a.reshape(1, -1)

b设置为a的另一种形状,可以得到相同的结果,而且读者更容易理解。对于a,我们不知道它应该有多少列(设置为-1!),但我们想要一个一维数组(设置第一个参数为1!)

提供新形状需要满足的条件是“新形状应该与原始形状兼容”

Numpy允许我们给出一个新的形状参数为-1(例如:(2,-1)或(-1,3),但不是(-1,-1))。它只是意味着它是一个未知的维度,我们想让numpy来计算它。numpy将通过查看'数组长度和剩余维度'并确保它满足上述标准来计算此值

现在请看示例。

z = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
z.shape
(3, 4)

现在尝试用(-1)来重塑。结果新形状为(12,)并且与原始形状(3,4)兼容

z.reshape(-1)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

现在尝试用(- 1,1)来重塑。我们将列设为1,而行设为未知。因此我们得到的结果是,新形状为(12,1)同样与原始形状(3,4)兼容

z.reshape(-1,1)
array([[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[12]])

以上与numpy建议/错误消息一致,对于单个特性使用reshape(-1,1);即单柱

如果数据有单一的功能,则使用array.reshape(-1, 1)重塑数据

新形状为(-1,2).行未知,列2。结果是(6,2)

z.reshape(-1, 2)
array([[ 1,  2],
[ 3,  4],
[ 5,  6],
[ 7,  8],
[ 9, 10],
[11, 12]])

现在尽量不让专栏人知道。新形状为(1,-1)。也就是说,行为1,列为未知。我们得到的结果是(1,12)

z.reshape(1,-1)
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]])

以上与numpy建议/错误消息一致,对单个示例使用reshape(1,-1);即单行

如果数据包含单样本,则使用array.reshape(1, -1)重塑数据

新形状(2,-1)。第二行,未知列。结果是(2,6)

z.reshape(2, -1)
array([[ 1,  2,  3,  4,  5,  6],
[ 7,  8,  9, 10, 11, 12]])

新形状为(3,-1)。第三行,未知列。结果是(3,4)

z.reshape(3, -1)
array([[ 1,  2,  3,  4],
[ 5,  6,  7,  8],
[ 9, 10, 11, 12]])

最后,如果我们试图提供两个维度为未知,即新形状为(-1,-1)。它会抛出一个错误

z.reshape(-1, -1)
ValueError: can only specify one unknown dimension

用于重塑数组。

假设我们有一个三维数组,大小为2 x 10 x 10:

r = numpy.random.rand(2, 10, 10)

现在我们要重塑为5 X 5 X 8:

numpy.reshape(r, shape=(5, 5, 8))

会完成任务的。

注意,一旦你修复了第一个dim = 5和第二个dim = 5,你就不需要确定第三个维度了。为了帮助你的懒惰,Numpy提供了使用-1的选项:

numpy.reshape(r, shape=(5, 5, -1))

会给你一个shape = (5, 5, 8)的数组。

同样的,

numpy.reshape(r, shape=(50, -1))

会得到一个数组shape = (50,4)

你可以在http://anie.me/numpy-reshape-transpose-theano-dimshuffle/上阅读更多

长话短说:你设置一些维度,让NumPy设置剩下的。

(userDim1, userDim2, ..., -1) -->>


(userDim1, userDim1, ..., TOTAL_DIMENSION - (userDim1 + userDim2 + ...))

这仅仅意味着您不确定您可以给出多少行或列,并且您要求numpy建议重新塑造的列或行数。

numpy提供了-1的最后一个示例 # EYZ0 < / p >

检查下面的代码及其输出,以更好地理解关于(-1):

代码:

import numpy
a = numpy.matrix([[1, 2, 3, 4], [5, 6, 7, 8]])
print("Without reshaping  -> ")
print(a)
b = numpy.reshape(a, -1)
print("HERE We don't know about what number we should give to row/col")
print("Reshaping as (a,-1)")
print(b)
c = numpy.reshape(a, (-1,2))
print("HERE We just know about number of columns")
print("Reshaping as (a,(-1,2))")
print(c)
d = numpy.reshape(a, (2,-1))
print("HERE We just know about number of rows")
print("Reshaping as (a,(2,-1))")
print(d)

输出:

Without reshaping  ->
[[1 2 3 4]
[5 6 7 8]]
HERE We don't know about what number we should give to row/col
Reshaping as (a,-1)
[[1 2 3 4 5 6 7 8]]
HERE We just know about number of columns
Reshaping as (a,(-1,2))
[[1 2]
[3 4]
[5 6]
[7 8]]
HERE We just know about number of rows
Reshaping as (a,(2,-1))
[[1 2 3 4]
[5 6 7 8]]
import numpy as np
x = np.array([[2,3,4], [5,6,7]])


# Convert any shape to 1D shape
x = np.reshape(x, (-1)) # Making it 1 row -> (6,)


# When you don't care about rows and just want to fix number of columns
x = np.reshape(x, (-1, 1)) # Making it 1 column -> (6, 1)
x = np.reshape(x, (-1, 2)) # Making it 2 column -> (3, 2)
x = np.reshape(x, (-1, 3)) # Making it 3 column -> (2, 3)


# When you don't care about columns and just want to fix number of rows
x = np.reshape(x, (1, -1)) # Making it 1 row -> (1, 6)
x = np.reshape(x, (2, -1)) # Making it 2 row -> (2, 3)
x = np.reshape(x, (3, -1)) # Making it 3 row -> (3, 2)

转换的最终结果是最终数组中的元素数量与初始数组或数据帧的元素数量相同。

-1对应行或列的未知计数。 我们可以认为它是x(未知)。x通过将原始数组中的元素数量除以有序对中的另一个值(-1)得到

例子:

reshape(-1,1)的12个元素对应于x=12/1=12行1列的数组。


带有reshape(1,-1)的12个元素对应于一个包含1行和x=12/1=12列的数组。

我没有设法理解np.reshape()是做什么的,直到我读了这篇文章

从机械上讲,reshape()的作用很清楚。但我们如何解读重塑前后的数据呢?

我所缺少的是:

当我们训练机器学习模型时,数组的嵌套层具有精确定义的含义。

这意味着重塑操作必须敏锐地意识到在操作之前的两个点有任何意义:

  • 它所操作的数据(重塑输入的样子)
  • 算法/模型期望重塑后的数据是什么样子(重塑后的输出是什么样子)

例如:

外部数组包含观测值/行。内部数组包含列/特性。这导致了两种特殊情况,即我们要么有一个对一个特征的多个观察的数组,要么有一个对多个特征的单一观察。

更高级的例子: 看到# EYZ0 < / p >

编辑:增加了更详细的例子,见下文。

场景

我们有3组/副本的以下内容:

fig

(图中为1组)

所有东西都被平化,因此emb (3 src节点,emb_size=32)是torch.Size([3, 32])。和,emb的6 tgt节点torch.Size([6, 32])

fig2

目标

我们希望重塑数据,以便每个src对应2个tgt节点,因此我们这样做:

fig3

现在,对于第i个src节点,我们有:

  • # EYZ0
  • 对应的target_embs[i,:,:]
  • 这就是关键所在:数据现在被整齐地组织起来了,如果没有重塑,我们就不能做这个简单的索引。

细节

target_embs的形状:

  • 在重塑之前,形状是[6,32]
  • 我们从最右边的暗淡开始,dim1=32,它在重塑中没有改变,所以忽略
  • 我们将形状视为[6,*],现在最右边的暗淡是dim0=6,几乎像忽略dim1,并将其视为[6]
  • 当我们将[6]重塑为[3,2]时,我们总是首先查看最右边的暗淡,所以我们取2元素,然后改变行,然后2元素,然后改变行,以此类推
  • 根据之前的知识,我们知道[6,*]对应于[src1_tgt1, src1_tgt2, src2_tgt1, src2_tgt2, src3_tgt1, src3_tgt2](这个输入必须是这种格式,否则我们需要将输入重新排列成这种格式)
  • 因此我们知道输出的格式是正确的:[3,2]将对应于我们想要的:[[src1_tgt1,src1_tgt2],[src2_tgt1, src2_tgt2],[src3_tgt1, src3_tgt2]]
  • 所以重塑[6,32][3,2,32]现在已经完成
  • 如果我们想把[6,32]重新塑造成[4,3,16]呢?Torch可以做到这一点,因为索引匹配,但结果对我们的目的是无用的
  • 如果我们想要[32,2,3]而不是[3,2,32]呢?我们只做reshape(input6x32,(32,2,3))吗?不。因为数据会被打乱,毫无意义。我们能做的是首先得到[3,2,32],然后使用transpose()[32,2,3]

摘要(基本使用)

  • 一次重塑两个连续的维度,而且只能重塑两个。这样就更容易理解了。
  • 如果要重塑非连续维度,则在重塑前进行转置
  • 可能还有更高级的用法,但这是我设法理解reshape()正在做什么的唯一方法。

当你使用-1(或任何其他负整数,我做这个测试kkk)在

b = numpy.reshape(a, -1)

你只是说numpy.reshape自动计算向量的大小(行x列),并将其重新定位到具有该维度的1-D向量。这个命令很有趣,因为它会自动为您执行。如果您希望通过输入正整数值将向量重新塑造为1-D,则只有在正确输入值“rows x columns"”时,reshape命令才会起作用。所以输入一个负整数会让这个过程更简单。

“在所有其他维度都已指定的情况下,推断出这个维度。”

显然,这将使-1维度成为原始数组的维度积与新指定的暗度的维度积的商。如果不是整数,则返回错误。

例如,对于形状为(2,3,5)的数组,下面这些都是等价的:

a = np.random.rand(2, 3, 5)


np.reshape(a, (-1,  2,  5))
np.reshape(a, ( 3, -1,  5))
np.reshape(a, ( 3,  2, -1))