Python numpy shape为(x,) 和 shape为(x,1)的区别

本文解析了NumPy中shape为(x,)与shape为(x,1)的区别,并通过实例演示了这两种不同形状数组在初始化、相乘、自身变化及相加过程中的表现差异。

Python numpy shape为(x,) 和 shape为(x,1)的区别

笔者最近在用numpy进行ML的学习,numpy确实方便,但是如果不仔细的话,还是会栽不少跟头,所以笔者在这里记录下遇到过的坑,方便大家学习。

稍微一看,shape为(x,)和shape为(x,1)几乎一样,都是一维的形式。其实不然:

  • (x,)意思是一维数组,数组中有2个元素
  • (x,1)意思是一个x维数组,每行有1个元素

这涉及到一个张量的概念,具体可以看:小昇的博客-Keras深度学习笔记(二):神经网络的数学基础

这里举几个例子来说明不重视这个点的危害。

  1. 初始化
a = np.arange(3)
print("a=" ,a.shape)
b = np.arange(15).reshape(5,3)
print("b=" ,b.shape)

输出:

a= (3,)
b= (5, 3)

可以看出,没有指明矩阵形式的时候,默认是一维数组。

  1. 相乘
c = np.dot(b,a)
print("c=" ,c.shape)

输出:

c= (5,)

矩阵乘法,因为a是一维的形式,所以b相乘之后,维数减少。

  1. 自身变化
c.reshape(c.shape[0],1)
print("c=" ,c.shape)
ff = c.reshape(c.shape[0],1)
print("ff=" ,ff.shape)

输出

c= (5,)
ff= (5, 1)

这里要注意的是,对自己reshape并不会改变自身的形式!只有赋值给其他变量才会看见效果。这很重要!

  1. 相加
c = np.arange(5)
print("c=" ,c.shape)
d = np.arange(5).reshape(5,1)
print("d=" ,d.shape)
e = c + d
print("c+d=" ,e.shape)

输出:

c= (5,)
d= (5, 1)
c+d= (5, 5)

一开始以为c会作用于d上的每个数据,直接相加,最后结果还是(5,1)。但是没想到会变成(5,5)这是矩阵相加最需要注意的地方

  1. 正确相加
c = np.arange(5)
print("c=" ,c.shape)
ff = c.reshape(c.shape[0],1)
print("ff=" ,ff.shape)
d = np.arange(5).reshape(5,1)
print("d=" ,d.shape)
e = ff + d
print("ff+d=" ,e.shape)

输出:

c= (5,)
ff= (5, 1)
d= (5, 1)
ff+d= (5, 1)

正如前面所说,需要先赋值给其他变量,然后再相加,此时才会得出正确结果。

小结:这个小细节曾连续困扰了我好几天,代码一直显示矩阵操作的维数不对,一点点调试才发现了这个问题。如果维数不对,那么结果也一定不对。希望和大家一起学习分享经验!

### 使用 `numpy.shape` 获取数组维度 在 Python 中,`numpy` 提供了一个属性 `.shape` 来获取数组的形状(即各维度上的大小)。`.shape` 返回的是一个元组,表示该数组每一维的长度。如果是一个二维数组,则返回 `(行数, 列数)`;如果是三维或多维数组,则依次类推。 以下是具体说明: #### 基本语法 对于任意 Numpy 数组 `arr`,可以通过以下方式访问其形状: ```python import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) print(arr.shape) # 输出 (2, 3),表示有两行三列 ``` 上述代码展示了如何通过 `.shape` 属性来查看数组的具体尺寸[^1]。 #### 多维数组的情况 当处理更高维度的数据时,`.shape` 同样适用。例如,创建一个三维数组并打印其形状: ```python b = np.arange(24).reshape(2, 3, 4) print(b.shape) # 输出 (2, 3, 4),表示这是一个 2×3×4 的三维数组 ``` 这里可以看到,`np.arange(24).reshape(2, 3, 4)` 创建了一个具有指定形状的三维数组,并且 `.shape` 正确反映了这一结构[^2]。 #### 修改数组形状后的效果 需要注意的是,在调用某些函数修改数组形状之后,原数组的 `.shape` 可能会发生变化。比如使用 `ravel()` 或者重新设置 `.shape` 属性都会影响到最终的结果。例如: ```python c = b.ravel() print(c.shape) # 输出 (24,),因为 ravel 将多维数组展平成了一维数组 ``` 此例子表明,经过 `ravel()` 方法处理后,原本复杂的多维数据被转换成了单一的一维向量形式[^3]。 另外一种情况是对现有数组直接调整其外形参数: ```python d = np.arange(12).reshape(3, 4) d.shape = (6, 2) print(d.shape) # 输出 (6, 2),显示新的行列配置已经生效 ``` 这段程序片段进一步验证了我们能够灵活操控 ndarray 对象的空间布局而不必担心底层存储模式的变化。 综上所述,无论是简单的矩阵还是复杂的大规模张量,都可以借助于 `.shape` 轻松读取它们当前所处的状态信息。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值