首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我使用元素乘法(*)时R和Python之间的不同广播规则

当我使用元素乘法(*)时R和Python之间的不同广播规则
EN

Stack Overflow用户
提问于 2022-01-26 16:22:51
回答 2查看 206关注 0票数 1

我在R和Python中尝试了矩阵和向量的元素乘法(*),得到了如下不同的结果。

这是R:

代码语言:javascript
复制
#R input
a=matrix(c(1,2,3,4,5,6,7,8),byrow=T,nrow=4)
b=c(9,10)
print(a)
print(b)
print(a*b)

#R output
# a
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
# b
[1]  9 10
# a*b
 [,1] [,2]
[1,]    9   18
[2,]   30   40
[3,]   45   54
[4,]   70   80

这是Python:

代码语言:javascript
复制
#Python input
a=np.array([[1,2],[3,4],[5,6],[7,8]])
b=np.array([9,10])
print(a)
print(b)
print(a*b)

#Python output
# a
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
# b
[ 9 10]
# a*b
[[ 9 20]
 [27 40]
 [45 60]
 [63 80]]

在执行*时,R和Python似乎不同地扩展了向量b。R使用以下矩阵逐元素乘一个元素:

代码语言:javascript
复制
     [,1] [,2]
[1,]    9    9
[2,]    10   10
[3,]    9    9
[4,]    10   10

Python使用以下矩阵:

代码语言:javascript
复制
[[ 9 10]
 [ 9 10]
 [ 9 10]
 [ 9 10]]

有人能解释一下为什么他们有不同的广播方式吗?Python是否有任何函数或操作符,其结果与R的结果相同?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-26 17:21:10

R代码使用回收规则,它表示,如果向量太短,它将被重复多次,以匹配其他操作数。Python代码使用numpy 广播规则,它描述了如果一个操作涉及不同形状的numpy数组会发生什么。这些规则是不一样的,因此得到了不同的结果。

有多种方法可以获得与R中使用numpy相同的结果。例如:

代码语言:javascript
复制
a * np.tile(b, (1,2)).T 

它规定:

代码语言:javascript
复制
array([[ 9, 18],
       [30, 40],
       [45, 54],
       [70, 80]])
票数 2
EN

Stack Overflow用户

发布于 2022-01-26 17:20:46

我不知道R,所以不会试图解释它的行为。

代码语言:javascript
复制
In [130]: a=np.array([[1,2],[3,4],[5,6],[7,8]])
     ...: b=np.array([9,10])
In [131]: a.shape
Out[131]: (4, 2)
In [132]: b.shape
Out[132]: (2,)
In [133]: a*b
Out[133]: 
array([[ 9, 20],
       [27, 40],
       [45, 60],
       [63, 80]])

numpy的广播规则如下

  • 根据需要添加前导尺寸
  • 根据需要调整尺寸1。

就你的情况而言,这相当于:

代码语言:javascript
复制
(4,2) * (2,) => (4,2) * (1,2) => (4,2) * (4,2) => (4,2)

b被视为一个(4,2)数组,其中2列中有910

代码语言:javascript
复制
In [134]: a*b.reshape(1,2)
Out[134]: 
array([[ 9, 20],
       [27, 40],
       [45, 60],
       [63, 80]])

numpy广播不像R显示的那样复制值,但您可以使用repeattile这样做:

代码语言:javascript
复制
In [139]: b1 = np.tile(b[:,None],(2,1))
In [140]: b1
Out[140]: 
array([[ 9],
       [10],
       [ 9],
       [10]])
In [141]: a*b1
Out[141]: 
array([[ 9, 18],
       [30, 40],
       [45, 54],
       [70, 80]])

这里的尺寸是

代码语言:javascript
复制
(4,2) * (4,1) => (4,2)

即使我将b设为(2,1),numpy也不会像R那样重复它:

代码语言:javascript
复制
In [144]: b[:,None]
Out[144]: 
array([[ 9],
       [10]])
In [145]: a*b[:,None]
Traceback (most recent call last):
  File "<ipython-input-145-a2236f333443>", line 1, in <module>
    a*b[:,None]
ValueError: operands could not be broadcast together with shapes (4,2) (2,1) 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70866779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档