【问题标题】:What is the definition of multiplication of jagged/ragged Numpy.array?锯齿状/锯齿状 Numpy.array 的乘法的定义是什么?
【发布时间】:2017-03-21 17:18:42
【问题描述】:

我不明白 Numpy.arrays 相乘时会发生什么。

例如,带有锯齿状(或参差不齐)的数组

import numpy as np
a = np.array([[1,2,3],[100,200]])
b = np.array([2, 4])
print(a * b)

我明白了

[[1, 2, 3, 1, 2, 3] [100, 200, 100, 200, 100, 200, 100, 200]]

但是,如果我稍微修改一下

import numpy as np
a = np.array([[1,2],[100,200]])
b = np.array([2, 4])
print(a * b)

我明白了

[[  2   8]
[200 800]]

我想找到数组乘法的定义。

【问题讨论】:

    标签: python numpy array-broadcasting


    【解决方案1】:

    我认为它“复制 ('a' 数组列 [x]) ('b' 数组索引 [x]) 次”。 如果您的目标是做乘法,请改用 NP.dot

    【讨论】:

    • 写完答案后,我终于明白了你的意思。你设法更简洁地表达了它。但是,np.dot 并没有好多少,因为包含列表的数组的潜在问题仍然存在。
    • 你可以去stackoverflow.com/questions/3890621/…那里有精彩的解释,我想你会感兴趣的
    • 您说得对,该链接背后有很多好的答案。但是,它们都与这里的这个问题无关,问题不是真正的乘法,而是(非常非标准的)锯齿状数组。
    • np.tensordot 有一个字符串复制的例子。
    【解决方案2】:

    基本上 numpy 数组 a*b 返回基本乘法,乘法应该像这样工作。

    Eg-1

    import numpy as np
    a = np.array([[1,2],[3,4]])
    b = np.array([[5,6],[7,8]])
    print(a * b)
    

    输出:

    [[ 5 12] [21 32]]
    

    Eg-2

    import numpy as np
    a = np.array([[1,2],[3,4]])
    b = np.array([5,6])
    print(a * b)
    

    输出:

    [[ 5 12] [15 24]]
    

    【讨论】:

    • 也就是说对数组的形式有要求。对吗?
    • 你的第一个例子是行为不端,因为每个列表的长度不一致。
    • 可以,但是对于这种行为,哪里可以查看官方文档
    • 我知道这个网站,但我找不到我要找的东西
    • 第一个例子是行为不端,这可能是我想要的。
    【解决方案3】:

    您的主要问题是您的数组a 不是“正常”数组,因为第二个维度不相等。 如果你尝试a.shape,你会得到(2,)a.dtype 给出dtype('O')(意思是对象),而a[0].dtype 会导致属性错误'list' object has no attribute 'dtype'。 这意味着你有一个维度为 2 的 numpy 数组,每个数组都包含一个 python 列表。

    您应该查找broadcasting,但这不是根本原因。如果数组在操作期间不匹配,它通常旨在将大小 1 的维度扩展到更大的值。它还有很多内容,但文档非常清楚。 对于您的具体问题,只需说广播意味着如果两个数组的维度匹配或其中一个为 1(从后到前计数,用 1 填充空值),则 numpy 不会引发错误。

    您有两个 (2,) 数组(a 包含 2 个列表,b 包含 2 个整数),这意味着尺寸适合(无需广播)。

    这个“错误行为”的其余部分(它不是)与 numpy 无关,因为在标准 python 中(因为a 包含 python 列表而起作用)将列表与标量重复并附加经常列出来。

    所以

    >>>[1, 2, 3] * 3
    [1, 2, 3, 1, 2, 3, 1, 2, 3]
    

    在您的情况下也会发生同样的事情:a 中的第一个列表乘以 2,第二个列表乘以 4

    【讨论】:

      【解决方案4】:

      np.tensordot 文档中的示例可能会有所帮助。它创建一个字符串对象数组,并显示dot 产生字符串复制。

      对于字符串和列表* 表示复制

      In [134]: 'abc'*3
      Out[134]: 'abcabcabc'
      

      你的数组:

      In [126]: a
      Out[126]: array([[1, 2, 3], [100, 200]], dtype=object)
      In [127]: b
      Out[127]: array([2, 4])
      

      还有一个字符串数组(我也可以做到a[:]=['a','B']

      In [128]: c = np.array(['a','B'],dtype=object)
      In [129]: c
      Out[129]: array(['a', 'B'], dtype=object)
      

      元素乘法 - 将 a 的元素复制 2 次和 3 次。

      In [130]: a*b
      Out[130]: array([[1, 2, 3, 1, 2, 3], [100, 200, 100, 200, 100, 200, 100, 200]], dtype=object)
      

      dot 产品 - 相同,但它对 * 之后的值进行“求和” - 列表的总和是连接。

      In [131]: a.dot(b)
      Out[131]: [1, 2, 3, 1, 2, 3, 100, 200, 100, 200, 100, 200, 100, 200]
      

      字符数组、复制和串联也会发生同样的情况。

      In [132]: c*b
      Out[132]: array(['aa', 'BBBB'], dtype=object)
      In [133]: c.dot(b)
      Out[133]: 'aaBBBB'
      

      在处理对象 dtype 数组时,numpy 本质上会遍历元素并应用定义该对象类的运算符/方法。

      a*b 生效

      In [147]: [i*j for i,j in zip(a,b)]
      Out[147]: [[1, 2, 3, 1, 2, 3], [100, 200, 100, 200, 100, 200, 100, 200]]
      

      numpy 版本有点花哨,可以处理多维数组并使用广播。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-20
        • 2013-01-02
        • 2020-04-02
        相关资源
        最近更新 更多