简体   繁体   English

Python 等效于 R 中的 (matrix)*(vector)

[英]Python equivalent of (matrix)*(vector) in R

In R, when I execute the code below:在 R 中,当我执行以下代码时:

> X=matrix(1,2,3)
> c=c(1,2,3)
> X*c

R gives out the following output: R给出以下output:

     [,1] [,2] [,3]
[1,]    1    3    2
[2,]    2    1    3

But when I do the below on Python:但是当我在 Python 上执行以下操作时:

>>> import numpy as np
>>> X=np.array([[1,1,1],[1,1,1]]) 
>>> c=np.array([1,2,3])
>>> X*c

the Python code above gives the following output:上面的 Python 代码给出了以下 output:

array([[1, 2, 3],
       [1, 2, 3]])

Is there any way that I can make the Python to come up with the identical output as R?有什么方法可以让 Python 拿出与 R 相同的 output 吗? I think I somehow have to tell Python that I want the numpy to multiply each element of the matrix X by each element of the vector c along the column, instead of along the row, but I am not sure how to go about this. I think I somehow have to tell Python that I want the numpy to multiply each element of the matrix X by each element of the vector c along the column, instead of along the row, but I am not sure how to go about this.

In [18]: np.reshape([1,2,3]*2,(2,3),order='F')                                  
Out[18]: 
array([[1, 3, 2],
       [2, 1, 3]])

This starts with a list multiply, which is replication:这从列表乘法开始,即复制:

In [19]: [1,2,3]*2                                                              
Out[19]: [1, 2, 3, 1, 2, 3]

The rest uses numpy to reshape it into a (2,3) array, but with consecutive values going down, 'F' order. rest 使用numpy将其重塑为 (2,3) 数组,但连续值下降,“F”顺序。

Not knowning R , and in particular the c(1,2,3) expression, I can't say that's what's going on in R .不知道R ,特别是c(1,2,3)表达式,我不能说这就是R中发生的事情。

=== ===

You talk about rows with columns, but I don't see how that works in your example.您谈论带有列的行,但在您的示例中我看不到它是如何工作的。 That said, we can easily perform outer like products也就是说,我们可以轻松地执行outer类似产品

=== ===

This reproduces your R_Product (at least in a few test cases):这会重现您的R_Product (至少在一些测试用例中):

In [138]: def foo(X,c): 
     ...:     X1 = X.ravel() 
     ...:     Y = np.resize(c,X1.shape)*X1 
     ...:     return Y.reshape(X.shape, order='F') 
     ...:                                                                       
In [139]: foo(np.ones((2,3)),np.arange(1,4))                                    
Out[139]: 
array([[1., 3., 2.],
       [2., 1., 3.]])
In [140]: foo(np.arange(6).reshape(2,3),np.arange(1,4))                         
Out[140]: 
array([[ 0,  6,  8],
       [ 2,  3, 15]])

I'm using the resize function to replicate c to match the total number of elements of X .我正在使用resize function 来复制c以匹配X的元素总数。 And order F to stack them in the desired column order.order F以所需的列顺序堆叠它们。 The default for numpy is order C. numpy的默认值为订单 C。

In numpy replicating an array to match another is not common, at least not in this sense.numpy ,复制一个数组以匹配另一个数组并不常见,至少在这个意义上不常见。 Replicating by row or column, as in broadcasting is common.像广播一样,按行或列复制是很常见的。 And of course reshaping.当然还有重塑。

I am the OP.我是OP。 I was looking for a quick and easy solution, but I guess there is no straightforward functionality in Python that allows us to do this.我一直在寻找一种快速简便的解决方案,但我想 Python 中没有简单的功能可以让我们做到这一点。 So, I had to make a function that multiplies a matrix with a vector in the same manner that R does:所以,我必须制作一个 function 以与 R 相同的方式将矩阵与向量相乘:

def R_product(X,c):

"""
Computes the regular R product 
(not same as the matrix product) between 
a 2D Numpy Array X, and a numpy vector c.

Args:
   X: 2D Numpy Array
   c: A Numpy vector

Returns: the output of X*c in R. 
         (This is different than X/*/c in R)
"""
    X_nrow = X.shape[0]
    X_ncol = X.shape[1]
    X_dummy = np.zeros(shape=((X_nrow * X_ncol),1))
    nrow = X_dummy.shape[0]
    nc = nrow // len(c)
    Y = np.zeros(shape=(nrow,1))

    for j in range(X_ncol):
        for u in range(X_nrow):
            X_element = X[u,j]
                
            if u == X_nrow - 1:
                idx = X_nrow * (j+1) - 1 
            else:
                idx = X_nrow * j + (u+1) - 1
                    
            X_dummy[idx,0] = X_element

    for i in range(nc):
        for j in range(len(c)):
            Y[(i*len(c)+j):(i*len(c)+j+1),:] = (X_dummy[(i*len(c)+j):(i*len(c)+j+1),:]) * c[j]
     
    for z in range(nrow-nc*len(c)):
        Y[(nc*len(c)+z):(nc*len(c)+z+1),:] = (X_dummy[(nc*len(c)+z):(nc*len(c)+z+1),:]) * c[z]

    return Y.reshape(X_ncol, X_nrow).transpose() # the answer I am looking for

Should work.应该管用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM