熊猫:矩阵乘法

时间:2017-07-05 23:24:39

标签: python python-3.x pandas numpy matrix-multiplication

我试图找到使用pandas进行矩阵乘法的最佳方法。假设我想做一个简单的练习:xyx'... [1x5] [5x5] [5x1]'。

in:

ydates = pd.date_range('20170101',periods=5)
y = pd.DataFrame(np.identity(5),index=['f','o','b','a','r'],columns=['f','o','b','a','r'])
xdata = list(range(1,6))
x = pd.DataFrame(xdata,index=['f','o','b','a','r'])
x.loc['o'] = np.nan
mm = x.T.dot(y)*x.T  



out: 

        f   o   b   a   r
    0 NaN NaN NaN NaN NaN

我希望得到:

     0
f  1.0
o  NaN
b  3.0
a  4.0
r  5.0

我的问题是:

1)如何对齐这些?有没有比做双重转置更好的方法?

2)有没有办法解释nans?

2)使用python / pandas进行矩阵代数是否有更有效的方法?

1 个答案:

答案 0 :(得分:0)

numpy有几个处理矩阵产品的函数 - np.dotnp.einsumnp.matmul(以及@运算符)。 *被定义为元素乘法(np.matrix类除外)。所有都针对速度进行了优化但他们也传播nan

使用numpy数组而不是pandas:

In [314]: y = np.eye(5)
In [316]: y
Out[316]: 
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  1.]])

要在x进行转置,我们需要将其设为2d;并指定nan它必须是浮动的。

In [320]: x = np.arange(1,6).astype(float).reshape(1,5)
In [321]: x[0,1]=np.nan
In [322]: x
Out[322]: array([[  1.,  nan,   3.,   4.,   5.]])
In [323]: x.T       # column vector
Out[323]: 
array([[  1.],
       [ nan],
       [  3.],
       [  4.],
       [  5.]])
In [324]: np.dot(y, x.T)
Out[324]: 
array([[ nan],
       [ nan],
       [ nan],
       [ nan],
       [ nan]])

为什么会出现dot结果?它将y的每一行乘以x.T的列,并对这些值求和。由于nan每行的y个产品之一为1*nan0*nan;涉及nan的任何产品或总和产生nan,结果全部为nan

我怀疑你希望0*nan == 0。像:

In [329]: x[0,1]=100
In [330]: np.dot(y, x.T)
Out[330]: 
array([[   1.],
       [ 100.],
       [   3.],
       [   4.],
       [   5.]])

有些numpy个函数会跳过nannp.dot不是其中之一。

In [333]: x[0,1]=np.nan
In [336]: y*x
Out[336]: 
array([[  1.,  nan,   0.,   0.,   0.],
       [  0.,  nan,   0.,   0.,   0.],
       [  0.,  nan,   3.,   0.,   0.],
       [  0.,  nan,   0.,   4.,   0.],
       [  0.,  nan,   0.,   0.,   5.]])
In [339]: np.nansum(y*x, axis=1, keepdims=True)
Out[339]: 
array([[ 1.],
       [ 0.],
       [ 3.],
       [ 4.],
       [ 5.]])

这种作品。在对行进行求和时,它跳过nan;但第二个值是0,而不是nan

np.nan...函数的工作原理是暂时将nan替换为无关紧要的内容,例如0或1.我可以在您的情况下执行以下操作:

In [369]: x
Out[369]: array([[  1.,  nan,   3.,   4.,   5.]])
In [370]: x1, mask = np.lib.nanfunctions._replace_nan(x.T,1)
In [371]: x1
Out[371]: 
array([[ 1.],
       [ 1.],
       [ 3.],
       [ 4.],
       [ 5.]])
In [372]: mask
Out[372]: 
array([[False],
       [ True],
       [False],
       [False],
       [False]], dtype=bool)
In [373]: x2 = np.dot(y, x1)
In [374]: x2[mask] = np.nan
In [375]: x2
Out[375]: 
array([[  1.],
       [ nan],
       [  3.],
       [  4.],
       [  5.]])