Numpy的reshape在方阵上表现不同

huangapple go评论120阅读模式
英文:

Numpy reshape behaves differently on square matrices

问题

The error you're encountering when trying to reshape the data is because the total number of elements in the weights array is not the same in both cases.

In the first case:

weights = [
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
]

There are a total of 30 elements in this 5x2 array. When you try to reshape it into a shape of (2, 5), it expects 2 * 5 = 10 elements, but you have 30, hence the error.

In the second case:

weights = [
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
]

In this case, there are 40 elements in the 5x2 array. When you reshape it to (2, 5), it also expects 10 elements, which matches the number of elements in the reshaped array.

So, the reshape operation works in the second case because the number of elements in the original array and the target shape match, but in the first case, they do not match, leading to the error.

英文:

I have the following data:

weights = [
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
]

len_models = len(weights)
len_layers = len(weights[0])

If I try to reshape the data as such: x = np.reshape(weights, (len_layers, len_models)), I'm getting an error:
> cannot reshape array of size 30 into shape (2,5)

However, if the weights have the following values:

weights = [
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
]

The reshape operation works.

Why is that?

答案1

得分: 2

你应该将形状视为 np.arrays

weights = np.array([
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
])
weights.shape # (5,2,3)
weights.dtype # dtype('int32')

为什么仅重塑为 (5,2) 是不可能的,现在应该很明显。

第二种情况:

weights = np.array([
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
])
weights.shape # (5,2)
weights.dtype # dtype('O')

第三个维度的长度不同(3 和 4),这会创建一个将第三个维度视为“一个”块的对象数组。这也通过警告指示:

VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])])
英文:

You should look at the shapes as np.arrays:

weights = np.array([
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3])]),
])
weights.shape # (5,2,3)
weights.dtype # dtype('int32')

Why reshaping to just (5,2) is not possible should be obvious now.

The second case:

weights = np.array([
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
    np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])]),
])
weights.shape # (5,2)
weights.dtype # dtype('O')

The 3rd dimension is of different length (3 and 4) which creates an array of objects that treats the 3rd dimension as "one" blob. This is also indicated by a warning:

> VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
np.array([np.array([1, 2, 3]), np.array([1, 2, 3, 4])])

huangapple
  • 本文由 发表于 2023年5月7日 23:37:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定