Numpy中的那些坑点

numpy中的坑点主要来自于shape、ndim、broadcast几方面,接下来将做详细分析

行向量 & 列向量 & 1-D数组

  • 上述3个概念,主要区别于shape,这将引起很多差异

  • termshapeexample
    col-vector(m, 1)[[1], [2], [3]]
    row-vector(1, m)[[1, 2, 3]]
    1-D array(m,)[1, 2, 3]
  • 通过观察上述表格,可以发现不论是哪种term,其本质都是array,其中col-vector 和 row-vector都是 2-D array

  • 1-D array和 vector的相互转化主要借助于reshape函数,也可以采用其他**ndim改变手段****

    # (m,) -> (m, 1) | (1, m)
    cv = a.reshape((-1, 1)) # rv = a.reshape((1, -1))
    v = np.array([a])
    # (m, 1) <-> (1, m)
    rv = cv.T # cv = rv.T
    # (m, 1) | (1, m) -> (m,)
    a = v.shape(-1)
    

矩阵乘法 & np.dot()

  • np.dot(a, b)并不是专门用来做矩阵乘法的,并且需要注意的是矩阵shape不合适时,会通过broadcast改造a、b,但这有时会带来很多麻烦

  • 官网文档表明,对于不同类型的a、b,np.dot(a, b)会有不同的行为

    • If both a and b are 1-D arrays, it is inner product of vectors (without complex conjugation).
    • If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or a @ b is preferred.
    • If either a or b is 0-D (scalar), it is equivalent to multiply and using numpy.multiply(a, b) or a * b is preferred.
    • If a is an N-D array and b is a 1-D array, it is a sum product over the last axis of a and b.
    • If a is an N-D array and b is an M-D array (where M>=2), it is a sum product over the last axis of a and the second-to-last axis of b:
  • 如果两个矩阵都是1-D的,则相当于**点积(内积)****

  • 针对 1-D x 2-D2-D x 1D 情形,说明如下:

    X = np.arange(16).reshape((4, 4)) # 2-D
    x = np.ones(4) # 1-D
    # 1-D x 2-D
    a = np.dot(x, X)
    # reuslt: array([ 6., 22., 38., 54.])
    # 2-D x 1-D
    b = np.dot(X, x)
    # reuslt: array([ 6., 22., 38., 54.])
    

    计算过程如下图, 可以认为:

    • 矩阵为1-D 时,可以把(m, )当做(1, m)来用,从而构成一个常规的矩阵乘法
    • 矩阵为1-D时,相当于对左矩阵在axis-0上做加权和 😭真令人迷惑!
img

点积 & np.vdot()

  • np.vdot(a, b)是专门用于向量点积的函数
  • 对于任何数学实质是1-D向量的变量(包括 行向量、列向量、1-D 数组),作用都是点积,a、b的顺序无所谓
  • 对于 n-D 向量 ,都将被flatten成一个长长的 1-D 向量, 然后执行点积操作
a = np.array([[1, 4], [5, 6]])
b = np.array([[4, 1], [2, 2]])
np.vdot(a, b) # 1*4 + 4*1 + 5*2 + 6*2
# result: 30 

np.array 切片 & 索引

  • 一般情况下,切片没什么好说的
  • 当切片的结果为1行/1列时,结果总会作为1-D array
X = np.arange(16).reshape((4, 4))
X[:, 0]
# result: array([0, 4, 8, 12])
X[0, :]
# result: array[0, 1, 2, 3]
  • 对于2-D的行向量或者列向量,可以仅有时直接用**x[0]**来得到 x 0 x_0 x0的引用(值),这与x[0, 0]效果相同
x = np.ones((4, 1))
y = np.ones((1, 4))
z = np.ones(4)

x[0]
# result: array([1])
y[0]
# result: array([1, 1, 1, 1])
z[0]
# result: 1

x[0] = 9
# result: x -> array([[9], [1], [1], [1]])
y[0] = 9
# result: y -> array([[9, 9, 9, 9]])
z[0] =9
# result: y -> array([9, 1, 1, 1])

总结

  • 综上所述,我们需要特别关注 array 的 shape、ndim
  • 1-D arraynp.dot() 中可当做行向量列向量索引时可当做 1-D array

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[2\]提到了一个类似的问题,即在for循环出现了"numpy.float64 object is not iterable"的错误。这个错误通常是由于尝试对一个浮点数进行迭代操作而导致的。在你的代码,当x_mat是一维数组时,x_mat\[0\]是一个浮点数,无法进行循环操作,从而导致了这个错误。为了解决这个问题,你可以在循环之前添加一个判断条件,判断x_mat是否为一维数组,如果是,则直接将x_mat赋值给x_norm,否则再进行循环操作。以下是一个可能的解决方案: if len(x_mat.shape) == 1: x_norm = x_mat else: for i in range(len(x_mat)): x_norm\[i\] = \[math.atan(temp_x)*2/math.pi for temp_x in x_mat\[0\]\] 这样,当x_mat是一维数组时,直接将x_mat赋值给x_norm,避免了对浮点数进行循环操作,从而解决了这个错误。希望这个解决方案对你有帮助。 #### 引用[.reference_title] - *1* [ValueError: TypeError(“‘numpy.float32‘ object is not iterable](https://blog.csdn.net/weixin_45717984/article/details/126952928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [TypeError: numpy.float64 object is not iterable 填坑之路](https://blog.csdn.net/woodG66/article/details/103289778)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值